轉載,原文連接: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並對字數求和。
下面來看更多命令用法,用於演示的類的基本代碼如下
- import static com.mongodb.client.model.Accumulators.*;
- import static com.mongodb.client.model.Aggregates.*;
- import static com.mongodb.client.model.Filters.eq;
- import java.text.ParseException;
- import java.util.Arrays;
- import org.bson.Document;
- import com.mongodb.Block;
- import com.mongodb.MongoClient;
- import com.mongodb.client.AggregateIterable;
- import com.mongodb.client.MongoCollection;
- import com.mongodb.client.MongoDatabase;
- public class AggregatesExamples {
- public static void main(String[] args) throws ParseException {
- //根據實際環境修改ip和端口
- MongoClient mongoClient = new MongoClient("localhost", 27017);
- MongoDatabase database = mongoClient.getDatabase("lesson");
- AggregatesExamples client = new AggregatesExamples(database);
- client.show();
- mongoClient.close();
- }
- private MongoDatabase database;
- public AggregatesExamples(MongoDatabase database) {
- this.database = database;
- }
- public void show() {
- MongoCollection<Document> mc = database.getCollection("blog");
- //每次執行前清空集合以方便重復運行
- mc.drop();
- //插入用於測試的文檔
- Document doc1 = new Document("title", "good day").append("owner", "tom").append("words", 300)
- .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")));
- Document doc2 = new Document("title", "good").append("owner", "john").append("words", 400)
- .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")));
- Document doc3 = new Document("title", "good night").append("owner", "mike").append("words", 200)
- .append("tag", Arrays.asList(1, 2, 3, 4));
- Document doc4 = new Document("title", "happiness").append("owner", "tom").append("words", 1480)
- .append("tag", Arrays.asList(2, 3, 4));
- Document doc5 = new Document("title", "a good thing").append("owner", "tom").append("words", 180)
- .append("tag", Arrays.asList(1, 2, 3, 4, 5));
- mc.insertMany(Arrays.asList(doc1, doc2, doc3, doc4, doc5));
- AggregateIterable<Document> iterable = mc.aggregate(Arrays.asList(match(eq("owner", "tom")),
- group("$author", sum("totalWords", "$words"))));
- printResult("", iterable);
- //TODO: 將在這里填充更多聚合示例
- }
- //打印聚合結果
- public void printResult(String doing, AggregateIterable<Document> iterable) {
- System.out.println(doing);
- iterable.forEach(new Block<Document>() {
- public void apply(final Document document) {
- System.out.println(document);
- }
- });
- System.out.println("------------------------------------------------------");
- System.out.println();
- }
- }
如上面代碼所示,將把所有的聚合操作集中在show()方法中演示,並且在執行后打印結果集以觀察執行結果。下面用常用的聚合代碼填充show()方法
注意需要靜態導入:
import static com.mongodb.client.model.Accumulators.*;
import static com.mongodb.client.model.Aggregates.*;
- // $match 確定復合條件的文檔, 可組合多個條件
- iterable = mc.aggregate(Arrays.asList(match(and(eq("owner", "tom"), gt("words", 300)))));
- printResult("$match only", iterable);
- // $sum求和 $avg平均值 $max最大值 $min最小值
- iterable = mc.aggregate(Arrays.asList(
- match(in("owner", "tom", "john", "mike")),
- group("$owner", sum("totalWords", "$words"),
- avg("averageWords", "$words"),
- max("maxWords", "$words"), min("minWords", "$words"))));
- printResult("$sum $avg $max $min", iterable);
- // $out 把聚合結果輸出到集合
- mc.aggregate(Arrays.asList(
- match(in("owner", "tom", "john", "mike")),
- group("$owner", sum("totalWords", "$words"),
- avg("averageWords", "$words"),
- max("maxWords", "$words"), min("minWords", "$words")),
- out("wordsCount")));
- iterable = database.getCollection("wordsCount").aggregate(
- Arrays.asList(sample(3)));
- printResult("$out", iterable);
- // 隨機取3個文檔, 僅返回title和owner字段
- iterable = mc.aggregate(Arrays.asList(sample(3),
- project(fields(include("title", "owner"), excludeId()))));
- printResult("sample(3)", iterable);
- // 從第2個文檔開始取2個文檔, 僅返回title和owner字段
- iterable = mc.aggregate(Arrays.asList(skip(1), limit(2),
- project(fields(include("title", "owner"), excludeId()))));
- printResult("skip(1), limit(2)", iterable);
- // $lookup 和另一個集合關聯
- database.getCollection("scores").drop();
- database.getCollection("scores").insertMany(
- Arrays.asList(
- new Document("writer", "tom").append("score", 100),
- new Document("writer", "joe").append("score", 95),
- new Document("writer", "john").append("score", 80)));
- iterable = mc.aggregate(Arrays.asList(lookup("scores", "owner",
- "writer", "joinedOutput")));
- printResult("lookup", iterable);
- // 拆分comments為單個文檔
- iterable = mc.aggregate(Arrays.asList(match(size("comments", 2)),
- project(fields(include("comments"), excludeId())),
- unwind("$comments")));
- printResult("unwind comments", iterable);
- System.out.println("distinct");
- DistinctIterable<String> di = mc.distinct("owner", String.class);
- di.forEach(new Block<String>() {
- public void apply(final String str) {
- System.out.println(str);
- }
- });
- System.out.println("------------------------------------------------------");
- System.out.println();
- System.out.println("count");
- long count = mc.count(Filters.eq("owner", "tom"));
- System.out.println("count=" + count);
- System.out.println("------------------------------------------------------");
- System.out.println();
- System.out.println("mapreduce");
- String map = "function() { var category; "
- + "if ( this.words >= 280 ) category = 'Long blogs'; "
- + "else category = 'Short blogs'; "
- + "emit(category, {title: this.title});}";
- String reduce = "function(key, values) { var cnt = 0; "
- + "values.forEach(function(doc) { cnt += 1; }); "
- + "return {count: cnt};} ";
- MapReduceIterable<Document> mi = mc.mapReduce(map, reduce);
- mi.forEach(new Block<Document>() {
- public void apply(final Document str) {
- System.out.println(str);
- }
- });
- System.out.println("------------------------------------------------------");
- System.out.println();
(完)