mongodb聚合查詢
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聚合查詢