MongoDB-JAVA-Driver 3.2版本常用代碼全整理(3) - 聚合


轉載,原文連接:http://blog.csdn.net/autfish/article/details/51379379

MongoDB的3.x版本Java驅動相對2.x做了全新的設計,類庫和使用方法上有很大區別。例如用Document替換BasicDBObject、通過Builders類構建Bson替代直接輸入$命令等,本文整理了基於3.2版本的常用增刪改查操作的使用方法。為了避免冗長的篇幅,分為增刪改、查詢、聚合、地理索引等幾部分。

聚合用於統計文檔個數、求和、最大最小值、求平均值等,功能和函數名稱和SQL中的count、distinct、group等關鍵字非常類似,此外,還可以通過JavaScript編寫MapReduce實現復雜的計算(性能損耗也會非常嚴重)。

首先來看3.x驅動中的聚合方法的聲明:

AggregateIterable<TDocument> aggregate(List<? extends Bson> pipeline)

參數類型是一個Bson的列表,而參數名稱是pipeline,其構建方式正如其名,是以多個Bson建立起一條管道,前一個Bson的輸出將作為后一個Bson的輸入,例如:

mc.aggregate(Arrays.asList(match(eq("owner", "tom")), group("$author", sum("totalWords", "$words"))));

首先用$match查找出owner=tom的文檔,並將結果集傳遞給$group並對字數求和。

下面來看更多命令用法,用於演示的類的基本代碼如下

 

[java]  view plain  copy
 
 print?在CODE上查看代碼片派生到我的代碼片
  1. import static com.mongodb.client.model.Accumulators.*;  
  2. import static com.mongodb.client.model.Aggregates.*;  
  3. import static com.mongodb.client.model.Filters.eq;  
  4.   
  5. import java.text.ParseException;  
  6. import java.util.Arrays;  
  7.   
  8. import org.bson.Document;  
  9.   
  10. import com.mongodb.Block;  
  11. import com.mongodb.MongoClient;  
  12. import com.mongodb.client.AggregateIterable;  
  13. import com.mongodb.client.MongoCollection;  
  14. import com.mongodb.client.MongoDatabase;  
  15.   
  16. public class AggregatesExamples {  
  17.   
  18.     public static void main(String[] args) throws ParseException {  
  19.         //根據實際環境修改ip和端口  
  20.         MongoClient mongoClient = new MongoClient("localhost", 27017);  
  21.         MongoDatabase database = mongoClient.getDatabase("lesson");  
  22.           
  23.         AggregatesExamples client = new AggregatesExamples(database);  
  24.         client.show();  
  25.         mongoClient.close();  
  26.     }  
  27.       
  28.     private MongoDatabase database;  
  29.     public AggregatesExamples(MongoDatabase database) {  
  30.         this.database = database;  
  31.     }  
  32.       
  33.     public void show() {  
  34.         MongoCollection<Document> mc = database.getCollection("blog");  
  35.         //每次執行前清空集合以方便重復運行  
  36.         mc.drop();  
  37.           
  38.         //插入用於測試的文檔  
  39.         Document doc1 = new Document("title", "good day").append("owner", "tom").append("words", 300)  
  40.                 .append("comments", Arrays.asList(new Document("author", "joe").append("score", 3).append("comment", "good"), new Document("author", "white").append("score", 1).append("comment", "oh no")));  
  41.         Document doc2 = new Document("title", "good").append("owner", "john").append("words", 400)  
  42.                 .append("comments", Arrays.asList(new Document("author", "william").append("score", 4).append("comment", "good"), new Document("author", "white").append("score", 6).append("comment", "very good")));  
  43.         Document doc3 = new Document("title", "good night").append("owner", "mike").append("words", 200)  
  44.                 .append("tag", Arrays.asList(1, 2, 3, 4));  
  45.         Document doc4 = new Document("title", "happiness").append("owner", "tom").append("words", 1480)  
  46.                 .append("tag", Arrays.asList(2, 3, 4));  
  47.         Document doc5 = new Document("title", "a good thing").append("owner", "tom").append("words", 180)  
  48.                 .append("tag", Arrays.asList(1, 2, 3, 4, 5));  
  49.         mc.insertMany(Arrays.asList(doc1, doc2, doc3, doc4, doc5));  
  50.           
  51.         AggregateIterable<Document> iterable = mc.aggregate(Arrays.asList(match(eq("owner", "tom")),  
  52.                 group("$author", sum("totalWords", "$words"))));  
  53.         printResult("", iterable);  
  54.           
  55.         //TODO: 將在這里填充更多聚合示例  
  56.     }  
  57.       
  58.     //打印聚合結果  
  59.     public void printResult(String doing, AggregateIterable<Document> iterable) {  
  60.         System.out.println(doing);  
  61.         iterable.forEach(new Block<Document>() {  
  62.             public void apply(final Document document) {  
  63.                 System.out.println(document);  
  64.             }  
  65.         });  
  66.         System.out.println("------------------------------------------------------");  
  67.         System.out.println();  
  68.     }  
  69. }  

如上面代碼所示,將把所有的聚合操作集中在show()方法中演示,並且在執行后打印結果集以觀察執行結果。下面用常用的聚合代碼填充show()方法

 注意需要靜態導入:

import static com.mongodb.client.model.Accumulators.*;
import static com.mongodb.client.model.Aggregates.*;

[java]  view plain  copy
 
 print?在CODE上查看代碼片派生到我的代碼片
  1. // $match 確定復合條件的文檔, 可組合多個條件  
  2. iterable = mc.aggregate(Arrays.asList(match(and(eq("owner", "tom"), gt("words", 300)))));  
  3. printResult("$match only", iterable);  
  4.   
  5. // $sum求和 $avg平均值 $max最大值 $min最小值  
  6. iterable = mc.aggregate(Arrays.asList(  
  7.         match(in("owner", "tom", "john", "mike")),  
  8.         group("$owner", sum("totalWords", "$words"),  
  9.                 avg("averageWords", "$words"),  
  10.                 max("maxWords", "$words"), min("minWords", "$words"))));  
  11. printResult("$sum $avg $max $min", iterable);  
  12.   
  13. // $out 把聚合結果輸出到集合  
  14. mc.aggregate(Arrays.asList(  
  15.         match(in("owner", "tom", "john", "mike")),  
  16.         group("$owner", sum("totalWords", "$words"),  
  17.                 avg("averageWords", "$words"),  
  18.                 max("maxWords", "$words"), min("minWords", "$words")),  
  19.         out("wordsCount")));  
  20. iterable = database.getCollection("wordsCount").aggregate(  
  21.         Arrays.asList(sample(3)));  
  22. printResult("$out", iterable);  
  23.   
  24. // 隨機取3個文檔, 僅返回title和owner字段  
  25. iterable = mc.aggregate(Arrays.asList(sample(3),  
  26.         project(fields(include("title", "owner"), excludeId()))));  
  27. printResult("sample(3)", iterable);  
  28.   
  29. // 從第2個文檔開始取2個文檔, 僅返回title和owner字段  
  30. iterable = mc.aggregate(Arrays.asList(skip(1), limit(2),  
  31.         project(fields(include("title", "owner"), excludeId()))));  
  32. printResult("skip(1), limit(2)", iterable);  
  33.   
  34. // $lookup 和另一個集合關聯  
  35. database.getCollection("scores").drop();  
  36. database.getCollection("scores").insertMany(  
  37.         Arrays.asList(  
  38.                 new Document("writer", "tom").append("score", 100),  
  39.                 new Document("writer", "joe").append("score", 95),  
  40.                 new Document("writer", "john").append("score", 80)));  
  41. iterable = mc.aggregate(Arrays.asList(lookup("scores", "owner",  
  42.         "writer", "joinedOutput")));  
  43. printResult("lookup", iterable);  
  44.   
  45. // 拆分comments為單個文檔  
  46. iterable = mc.aggregate(Arrays.asList(match(size("comments", 2)),  
  47.         project(fields(include("comments"), excludeId())),  
  48.         unwind("$comments")));  
  49. printResult("unwind comments", iterable);  
  50.   
  51. System.out.println("distinct");  
  52. DistinctIterable<String> di = mc.distinct("owner", String.class);  
  53. di.forEach(new Block<String>() {  
  54.     public void apply(final String str) {  
  55.         System.out.println(str);  
  56.     }  
  57. });  
  58. System.out.println("------------------------------------------------------");  
  59. System.out.println();  
  60.   
  61. System.out.println("count");  
  62. long count = mc.count(Filters.eq("owner", "tom"));  
  63. System.out.println("count=" + count);  
  64. System.out.println("------------------------------------------------------");  
  65. System.out.println();  
  66.   
  67. System.out.println("mapreduce");  
  68. String map = "function() { var category; "  
  69.         + "if ( this.words >= 280 ) category = 'Long blogs'; "  
  70.         + "else category = 'Short blogs'; "  
  71.         + "emit(category, {title: this.title});}";  
  72.   
  73. String reduce = "function(key, values) { var cnt = 0; "  
  74.         + "values.forEach(function(doc) { cnt += 1; }); "  
  75.         + "return {count: cnt};} ";  
  76. MapReduceIterable<Document> mi = mc.mapReduce(map, reduce);  
  77. mi.forEach(new Block<Document>() {  
  78.     public void apply(final Document str) {  
  79.         System.out.println(str);  
  80.     }  
  81. });  
  82. System.out.println("------------------------------------------------------");  
  83. System.out.println();  

(完)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM