1、聚合查詢
聚合查詢主要使用聚合框架對(duì)集合中的文檔進(jìn)行變換與組合,以實(shí)現(xiàn)對(duì)文檔的一連串處理。這些處理包含篩選(Filtering)、投射(projecting)、分組(grouping)、排序(sorting)、限制(limiting)和跳過(skipping)。
聚合操作通過管道操作符進(jìn)行處理,每個(gè)操作符都會(huì)接受一連串的文檔,對(duì)這些文檔做一些類型轉(zhuǎn)換,最后將轉(zhuǎn)換后的文檔作為結(jié)果傳遞給下一個(gè)操作符。不同的管道操作符可以按任意順序組合在一起,而且可以被重復(fù)任意多次。
1.1、$match
$match用于對(duì)文檔集合進(jìn)行篩選,之后就可以在篩選的帶的文檔子集上做聚合。$match可以使用常規(guī)的查詢操作符,如$gt/$lt/$in等,但不能在$match中使用地理位置空間操作符。
通常在使用中應(yīng)盡可能將$match放在管道的前面位置。這樣好處為:一是可以快速將不需要的文檔過濾掉,以減少管道的工作量;二是如果在投射和分組之前執(zhí)行$match,查詢可以使用索引。
使用示例:
> db.city.aggregate({"$match":{"code":{$lt:2}}})
{ "_id" : ObjectId("5de52e826bba334fecac2f28"), "name" : "北京", "country" : "中國", "code" : 1, "captial" : true, "people" : 20009000, "district" : [ "朝陽1", "通州", "海淀", "大興" ], "north" : true, "subId" : [ 1, 10, 20, 50, 100 ] }
>
1.2、$project
$project可以從文檔中提取字段,可以重命名字段,還可以在這些字段上進(jìn)行一些操作。$project最簡(jiǎn)單的操作是選擇想要的字段,可以指定包含或不包含某個(gè)字段。同時(shí),也可將投射過的字段進(jìn)行重命名。$fieldName在聚合框架中的含義是引用某個(gè)字段的值。
1.2.1、管道表達(dá)式
最簡(jiǎn)單的$project表達(dá)式是包含和排除字段,以及字段名稱。也可以使用表達(dá)式將多個(gè)字面量和變量組合在一個(gè)值中使用。文檔的id默認(rèn)是包含的。
使用示例:
> db.city.aggregate({"$project":{"name":1,"code":1}})
{ "_id" : ObjectId("5de52e826bba334fecac2f28"), "name" : "北京", "code" : 1 }
{ "_id" : ObjectId("5de5ac646bba334fecac2f30"), "name" : "廣州", "code" : 3 }
{ "_id" : ObjectId("5de647f5b4cd9b14f46e0e30"), "name" : "上海", "code" : 2 }
>
1.2.2、數(shù)學(xué)表達(dá)式
數(shù)學(xué)表達(dá)式可用于操作數(shù)值。指定一組數(shù)值,就可以使用數(shù)學(xué)表達(dá)式進(jìn)行操作了。
操作語法如下:
- "$add":[ expr1 [ , expr2, … , exprN ] ]。這個(gè)操作符接受一個(gè)或多個(gè)表達(dá)式作為參數(shù),將這些表達(dá)式相加。
- "$subtract":[ expr1, expr2 ]。接受兩個(gè)表達(dá)式作為參數(shù),用第一個(gè)表達(dá)式減去第二個(gè)表達(dá)式作為結(jié)果。
- "$multiply":[ expr1 [ , expr2, … , exprN ] ]。接受一個(gè)或多個(gè)表達(dá)式,并將它們相乘。
- "$divide":[ expr1, expr2 ]。接受兩個(gè)表達(dá)式,用第一個(gè)表達(dá)式除以第二個(gè)表達(dá)式的商作為結(jié)果。
- "$mod":[ expr1, expr2 ]。接受兩個(gè)表達(dá)式作為,將第一個(gè)表達(dá)式作為除以第二個(gè)表達(dá)式得到的余數(shù)作為結(jié)果。
使用示例:
> db.city.aggregate({"$project":{"code+2":{"$add":["$code",2]},"code*2*2*2":{"$multiply":["$code",2,2,2]},"code%3":{"$mod":["$code",3]}}})
{ "_id" : ObjectId("5de52e826bba334fecac2f28"), "code+2" : 3, "code*2*2*2" : 8, "code%3" : 1 }
{ "_id" : ObjectId("5de5ac646bba334fecac2f30"), "code+2" : 5, "code*2*2*2" : 24, "code%3" : 0 }
{ "_id" : ObjectId("5de647f5b4cd9b14f46e0e30"), "code+2" : 4, "code*2*2*2" : 16, "code%3" : 2 }
>
1.2.3、日期表達(dá)式
聚合框架中包含了一些用于提取日期信息的表達(dá)式:"$year"、"$month"、"$dayOfMonth"、"$dayOfWeek"、"$dayOfYear"、"$hour"、"$minute"、"$second"。只能對(duì)日期類型的字段進(jìn)行日期操作,不能對(duì)數(shù)值類型的字段做日期操作。
使用示例:
> db.city.aggregate({"$project":{"crete_year":{"$year":"$create_date"}, "create_week":{"$dayOfWeek":"$create_date"}}})
{ "_id" : ObjectId("5de52e826bba334fecac2f28"), "crete_year" : null, "create_week" : null }
{ "_id" : ObjectId("5de5ac646bba334fecac2f30"), "crete_year" : null, "create_week" : null }
{ "_id" : ObjectId("5de647f5b4cd9b14f46e0e30"), "crete_year" : 2019, "create_week" : 5 }
>
1.2.4、字符串表達(dá)式
字符串操作如下:
- "$substr":[ expr, startOffset, numToReturn ]。這個(gè)操作會(huì)截取字符串的字串,startOffset為字節(jié)偏移量,- - - numToReturn為字節(jié)數(shù),expr為輸入字符串。
- "$concat":[ expr1, [ , expr2, … , exprN ] ]。將給定的字符串連接在一起返回結(jié)果;
- "$toLower":expr。返回expr字符串的小寫形式;
- "$toUpper":expr。返回expr字符串的大寫形式;
使用示例:
> db.city.aggregate({"$project":{"country_city":{"$concat":["$country","-","$name"]}}})
{ "_id" : ObjectId("5de52e826bba334fecac2f28"), "country_city" : "中國-北京" }
{ "_id" : ObjectId("5de5ac646bba334fecac2f30"), "country_city" : "中國-廣州" }
{ "_id" : ObjectId("5de647f5b4cd9b14f46e0e30"), "country_city" : "中國-上海" }
>
1.2.5、邏輯表達(dá)式
比較表達(dá)式:
- "$cmp":[ expr1, expr2 ]。比較expr1和expr2。若相等,返回0;若expr1<expr2,返回負(fù)數(shù);若expr1>expr2則返回正數(shù)。
- "$strcasecmp":[ string1, string2]。比較string1和string2,區(qū)分大小寫。只對(duì)羅馬字符組成的字符串有效。
- "$eq"、"$ne"、"$gt"、"$gte"、"$lt"、"$lte":[ expr1, expr2 ]。對(duì)expr1和expr2執(zhí)行相應(yīng)的比較操作,返回比較的結(jié)果(true或false)。
布爾表達(dá)式:
- "$and":[ expr1, [ , expr2, … , exprN ] ]。如果所有表達(dá)式的值都是true,那就返回true,否則返回false;
- "$or":[ expr1, [ , expr2, … , exprN ] ]。只要有任意表達(dá)式為true,則返回true,否則返回false。
- "$not":expr。對(duì)expr取反。
控制語句:
- "$cond":[ booleanExpr, trueExpr, falseExpr]。如果booleanExpr的值時(shí)true,那就返回trueExpr,否則返回falseExpr。
- "$ifNull":[ expr, replacementExpr]。如果expr是null,返回replacementExpr,否則返回expr。
使用示例:
> db.city.aggregate({"$project":{"hugeCity":{"$eq":["$name","北京"]}}})
{ "_id" : ObjectId("5de52e826bba334fecac2f28"), "hugeCity" : true }
{ "_id" : ObjectId("5de5ac646bba334fecac2f30"), "hugeCity" : false }
{ "_id" : ObjectId("5de647f5b4cd9b14f46e0e30"), "hugeCity" : false }
>
1.3、$group
$group操作可以將文檔依據(jù)特定字段的不同值進(jìn)行分組。