mongoTemplate的andExpression表達式
Aggregation<Post> agg = Aggregation.newAggregation( Record.class, match(Criteria.where("createAt").gte(startAt).lte(endAt)), project().andExpression("{$dateToString:{format:'%Y-%m-%d',date: {$add:{'$createAt',8*60*60000}}}}").as("createAt") ,group( "createAt").count().as("totalNum") ,sort(Sort.Direction.DESC, "createAt") ); AggregationResults<BasicDBObject> result = mongoTemplate.aggregate(agg, BasicDBObject.class); List<BasicDBObject> results = result.getMappedResults();
mongoTemplate中的project()的用法,和previousOperation()的用法
https://blog.csdn.net/hotdust/article/details/52605990
最近使用Spring-Data-Mongodb的API來改寫原來的代碼,遇到了一些問題,先把自己學到的一些東西總結下來。
參考:
http://www.cnblogs.com/ontheroad_lee/p/3756247.html (這個文章特別好,很少有中文的關於Spring-Data-Mongodb的API的例子的介紹)
http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo.aggregation.examples.example6 (官方文檔)
1,project("name", "netPrice")
project方法的內容是你要映射的字段,相當於{$project: {sumfavour: 1, userid: 1}}。“映射”的意思,就是要顯示哪個字段,或者把某個字段內容進行處理后顯示。
2,project().and("foo").as("bar")
如果你想要把一個字段映射成別一個名字的話,就可以用上面的方法,相當於{$project: {bar: $foo}}
3,project("a","b").and("foo").as("bar")
這個方法相當於上面兩個方法的結合{$project: {a: 1, b: 1, bar: $foo}}。如果單獨使用and(),后面不使用as()的話,沒有任何效果,也不會出錯。
4,project().and("_id").plus(100000000).as("statusid")
這個語句的意思是,把_id字段加上100000000,再重新命名為"statusid"然后輸出。
5,關於previousOperation()方法
Aggregation agg = newAggregation(
project("tags"),
unwind("tags"),
group("tags").count().as("n"),
project("n").and("tag").previousOperation(),
sort(DESC, "n")
);
這段代碼中主要講的是previousOperation()方法的使用,想知道其它語句的含義,請參考官網文章介紹。說previousOperation之前要先說說Group語句,這里的Group語句的作用是,按“tags”字段進行分組,然后統計每個分組中的數據個數,統計的個數字段命名為“n”。輸出的結果為(這里只為粘貼了所有數據中的一條):
{
"_id" : "627",
"n" : NumberInt(16)
}
project語句的作用是,把新生成的字段”n“做為結果輸出,並且”_id“列重新命名為”tag“,然后也做為結果輸出,最后結果為:
{
"tag" : "627",
"n" : NumberInt(16)
}
看完結果后,我們來說一下previousOperation()的作用。previousOperation()就是把“上一次操作的結果中”的_id字段,命名為它前面and()中的名稱。所以它一般都是和and()結合使用。關於Group操作后,_id的內容的介紹,請看最下面的“關於_id字段”說明。
6,
通過nested()方法,可以把輸出的結果變成嵌套格式,例如:
"object":{ "fieldA":"valueA","fieldB":"valueB"}
bind()方法是用通過已經存在的字段,來生成新的字段。例如
and("biggestCity").nested(bind("newField", "existField"))
7,
可以在映射完某個字段后,還可以對字段進行加減乘除。
8,
還可以用andExpression()方法,使用一些mongo中的函數,例如:substr等。更重要的一點,還可以使用SpringSpEL表達式。上面的例子就是使用了表達式。下面是使用和不使用表達式的例子:
使用表達式:
1+(q +1)/(q -1)
不使用表達式:
而且,而且,在表達式內部還可以設置用外部變量進行替換。
[0]的位置,就會被后面的shippingCosts參數的內容給替換。
關於_id字段
_id字段是插入到數據庫時自動生成的。在使用Group等聚合操作后,_id的內容會隨着變化。例如:
1,{$group:{_id:'$statusid', sumfavour:{$sum:1}}}
這個語句的意思是,按照statusid字段進行分組,並統計每個分組的數據個數,被統計的個數字段命名為“sumfavour”。
從下面的輸出的內容可以看到,_id內容就是statusid字段的內容。
{
"sumfavour" : NumberInt(16),
"statusid" : "627"
}
2,{$group:{_id:{'statusid':'$statusid','userid':'$userid'}, sumfavour:{$sum:1}}}
這個語句的意思是按兩個字段的內容進行排序。當以兩個或以上的字段進行分組時,必須這么寫,下面的例子都是錯誤的:
X:$group:{_id:{'$statusid','$userid'}}
X:$group:{_id:{'statusid','userid'}}
從這次分組完后的內容可以看到,_id的內容是statusid和userid兩個字段的內容的組合。
{
"_id" : {
"statusid" : NumberInt(538),
"userid" : NumberInt(416347)
},
"sumfavour" : NumberInt(1)
}
可以看出_id字段