MongoDB 3.2版本常用代码全整理(2) - 聚合

原文地址
MongoDB的3.x版本Java驱动相对2.x做了全新的设计,类库和使用方法上有很大区别。例如用Document替换BasicDBObject、通过Builders类构建Bson替代直接输入$命令等,本文整理了基于3.2版本的常用增删改查操作的使用方法。为了避免冗长的篇幅,分为增删改、查询、聚合、地理索引等几部分。

聚合用于统计文档个数、求和、最大最小值、求平均值等,功能和函数名称和SQL中的count、distinct、group等关键字非常类似,此外,还可以通过JavaScript编写MapReduce实现复杂的计算(性能损耗也会非常严重)。

首先来看3.x驱动中的聚合方法的声明:

AggregateIterable aggregate(List

[java] view plain copy print?在CODE上查看代码片派生到我的代码片
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()方法

// $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();  

(完)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值