1. 程式人生 > >mongodb聚合查詢

mongodb聚合查詢

類型 結構 對數 個數字 col 倒序 ron 介紹 catch

MongoDB中聚合(aggregate)主要用於處理數據(諸如統計平均值,求和等),並返回計算後的數據結果。有點類似sql語句中的 count(*)。

$sum 計算總和。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])
$avg 計算平均值 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])
$min 獲取集合中所有文檔對應值得最小值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])
$max 獲取集合中所有文檔對應值得最大值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])
$push 在結果文檔中插入值到一個數組中。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])
$addToSet 在結果文檔中插入值到一個數組中,但不創建副本。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])
$first 根據資源文檔的排序獲取第一個文檔數據。 db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])
$last 根據資源文檔的排序獲取最後一個文檔數據 db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])

表達式:處理輸入文檔並輸出。表達式是無狀態的,只能用於計算當前聚合管道的文檔,不能處理其它的文檔。

這裏我們介紹一下聚合框架中常用的幾個操作:

  • $project:修改輸入文檔的結構。可以用來重命名、增加或刪除域,也可以用於創建計算結果以及嵌套文檔。
  • $match:用於過濾數據,只輸出符合條件的文檔。$match使用MongoDB的標準查詢操作。
  • $limit:用來限制MongoDB聚合管道返回的文檔數。
  • $skip:在聚合管道中跳過指定數量的文檔,並返回余下的文檔。
  • $unwind:將文檔中的某一個數組類型字段拆分成多條,每條包含數組中的一個值。
  • $group:將集合中的文檔分組,可用於統計結果。
  • $sort:將輸入文檔排序後輸出。
  • $geoNear:輸出接近某一地理位置的有序文檔。

補充:

在mongodb中提供了很多與更新操作有關的方法,我們也可以叫它更新操作符。這些操作符主要可以分為兩類:字段和數組。

字段組的主要包括:$inc、$rename、$setOnInsert、$set、$unset。

數組組的主要包括:$addToSet、$pop、$pullAll、$pull、$pushAll、$push、$each、$slice、$sort。

$inc

  語法:db.collection.update({ field: value }, { $inc: { field1: amount } } );

  為一個字段添加加上一個值,這個方法只能對數字操作,也就是說只能給數字加上一個值,當然這個值可以是負數。

$set

  語法:db.collection.update({ field: value1 }, { $set: { field1: value2 } } );

  當文檔中包含該字段的時候,更新該字段值為value2,如果該文檔中沒有該字段,則為本文檔添加一個字段file1,並為其賦值給value2。

$unset

語法:db.collection.update({ field: value1 }, { $unset: { field1: <arg> } } );

參數arg可以使用true或者空字符串””,這樣都會刪除一個字段。

$rename

  語法:{$rename: { <old name1>: <newname1>, <old name2>: <new name2>, ... } }

  為文檔中的一個或者多個字段改名。

$setOnInsert

  語法:db.collection.update(<query>, { $setOnInsert:{ <field1>: <value1>, ... } },{upsert: true })

  $setOnInsert只有在upsert設置為true,並且被更新的文檔不存在此集合中,需要插入一個新的文檔的時候才起作用。在插入的時候會為新插入的文檔添加給定的字段。

$push

  語法:db.collection.update(<query>, { $push:{ <field>: <value> } })

  將一個數字存入一個數組,分為三種情況,如果該字段存在,則直接將數字存入數組.如果該字段不存在,創建字段並且將數字插入該數組.如果更新的字段不是數組,會報錯的.

$pushAll

  語法:db.collection.update({ field: value }, { $pushAll: { field1: [ value1, value2, value3 ] } } );

  將多個數值一次存入數組.

$addToSet

  語法:db.collection.update( { field: value }, {$addToSet: { field: value1 } } );

  與$push功能相同講一個數字存入數組,不同的是如果數組中有這個數字,將不會插入,只會插入新的數據,同樣也會有三種情況,與$push相同.

$pop

  語法:db.collection.update( {field: value }, { $pop:{ field:,<arg> } } )

  刪除數組最後一個或者第一個元素。如果參數arg設置為1,刪除最後一個元素,如果設置為-1,則刪除第一個元素。

$pull

  語法:db.collection.update( { field: <query> },{ $pull: { field: <query> } } );

  刪除數組中的一個元素,如果刪除的字段不是數組,會報錯。

$pullAll

  語法:db.collection.update( { field: value }, {$pushAll: { field1: [ value1, value2, value3 ] } } );

  刪除數組中的多個值,跟pushAll與push的關系類似.

$each

$each只能和$addToSet或者$push結合使用,將多個值一次存入數組。

$slice

  $slice需要和$push結合使用,截取一定長度的數組。參數num是小於或者等於0的數。如果num等於0表示的是返回的是一個空數組,如果是負數表示從後向前截取負數絕對值長度的數組。

$sort

  $sort將數組中的元素按照一定的規則進行排序,同樣1表示正序,-1表示倒序。

  $sort必須與$push、$each結合使用,並且$each值的數組中的元素都必須為對象。

註: 詳解 http://blog.csdn.net/mengxiangyue/article/details/18560357

在java中通過BasicDBObject使用:

BasicDBObject limit = new BasicDBObject();
-------------字段名-------------BasicDBObject("聚合表達式","條件")
limit.append("items", new BasicDBObject().append("$slice", new int[]{0, 15}));
  1 private static void mongodbOperating(){  
  2         try {  
  3             //有多種構造方法,選擇一種(IP、port)  
  4             Mongo m = new Mongo( "192.168.21.111" , 27017 );  
  5             //選擇數據庫,如果沒有這個數據庫的話,會自動建立  
  6             DB  db = m.getDB( "mydb" );  
  7   
  8             //建立一個集合,和數據庫一樣,如果沒有,會自動建立  
  9             DBCollection collection = db.getCollection("myCollectionTest");  
 10               
 11             BasicDBObject doc = new BasicDBObject();  
 12             doc.put("name", "MongoDB");  
 13             doc.put("type", "database");  
 14             doc.put("count", 1);  
 15   
 16             BasicDBObject info = new BasicDBObject();  
 17             info.put("x", 203);  
 18             info.put("y", 102);  
 19             doc.put("info", info);  
 20   
 21             //插入一條數據,數據如下  
 22             // {  
 23             //     "name" : "MongoDB",  
 24             //     "type" : "database",  
 25             //     "count" : 1,  
 26             //     "info" : {  
 27             //                 x : 203,  
 28             //                 y : 102  
 29             //               }  
 30             //  }  
 31             // 可以循環插入多條數據  
 32             collection.insert(doc);  
 33             //查找第一條數據,顯示如下,_id是系統自動幫加上的,全局唯一  
 34             //{ "_id" : "49902cde5162504500b45c2c" , "name" : "MongoDB" , "type" : "database" , "count" : 1 , "info" : { "x" : 203 , "y" : 102}}  
 35             DBObject myDoc = collection.findOne();  
 36             System.out.println(myDoc);  
 37               
 38             //插入多條數據  
 39             for (int i=0; i < 100; i++) {  
 40                 collection.insert(new BasicDBObject().append("i", i));  
 41             }  
 42   
 43               
 44             //獲取文檔條數  
 45             System.out.println(collection.getCount());  
 46               
 47             //使用Cursor 獲取所有文檔  
 48             DBCursor cursor = collection.find();  
 49             try {  
 50                 while(cursor.hasNext()) {  
 51                     System.out.println(cursor.next());  
 52                 }  
 53             } finally {  
 54                 cursor.close();  
 55             }  
 56               
 57             //查找操作,獲取單條記錄  
 58             //{ "_id" : "49903677516250c1008d624e" , "i" : 71 }  
 59             BasicDBObject query = new BasicDBObject();  
 60             query.put("i", 71);  
 61             cursor = collection.find(query);  
 62             try {  
 63                 while(cursor.hasNext()) {  
 64                     System.out.println(cursor.next());  
 65                 }  
 66             } finally {  
 67                 cursor.close();  
 68             }  
 69   
 70             //查找 i>50的項  
 71             query = new BasicDBObject();  
 72             query.put("i", new BasicDBObject("$gt", 50));  // e.g. find all where i > 50  
 73             cursor = collection.find(query);  
 74             try {  
 75                 while(cursor.hasNext()) {  
 76                     System.out.println(cursor.next());  
 77                 }  
 78             } finally {  
 79                 cursor.close();  
 80             }  
 81   
 82   
 83             //查找 20<i<=30  
 84             query = new BasicDBObject();  
 85             query.put("i", new BasicDBObject("$gt", 20).append("$lte", 30));  // i.e.   20 < i <= 30  
 86             cursor = collection.find(query);  
 87             try {  
 88                 while(cursor.hasNext()) {  
 89                     System.out.println(cursor.next());  
 90                 }  
 91             } finally {  
 92                 cursor.close();  
 93             }  
 94   
 95             //修改 i=71的一項  
 96             query = new BasicDBObject();  
 97             query.put("i", 71);  
 98             BasicDBObject update = new BasicDBObject();  
 99             update.put("i", 710);  
100             DBObject dbobj = collection.findAndModify(query, update);  
101             System.out.println(dbobj);  
102               
103             //修改 i=72的一項  
104             query = new BasicDBObject();  
105             query.put("i", 72);  
106             update = new BasicDBObject();  
107             update.put("i", 720);  
108             WriteResult result = collection.update(query, update);  
109             System.out.println(result);  
110               
111             //刪除i=61的項  
112             query = new BasicDBObject();  
113             query.put("i", 61);  
114             collection.findAndRemove(query);  
115             //刪除i=62的項  
116             BasicDBObject remove = new BasicDBObject();  
117             remove.put("i", 62);  
118             collection.remove(remove);  
119               
120             //創建索引 1為升序、-1為降序  
121             collection.createIndex(new BasicDBObject("i", 1));  // create index on "i", ascending  
122   
123             //獲取索引列表  
124             List<DBObject> list = collection.getIndexInfo();  
125             for (DBObject o : list) {  
126                 System.out.println(o);  
127             }  
128   
129             //獲取數據庫列表  
130             for (String s : m.getDatabaseNames()) {  
131                 System.out.println(s);  
132             }  
133             //獲取集合列表  
134             Set<String> colls = db.getCollectionNames();  
135             for (String s : colls) {  
136                 System.out.println(s);  
137             }  
138   
139             //刪除數據庫  
140             //m.dropDatabase("my_new_db");  
141               
142   
143         } catch (UnknownHostException e) {  
144             // TODO Auto-generated catch block  
145             e.printStackTrace();  
146         }  
147     }  



mongodb聚合查詢