简体   繁体   English

使用Java驱动程序进行MongoDB聚合

[英]MongoDB aggregation with Java driver

I need your help for using MongoDB aggregation framework with java driver. 我需要你帮助将MongoDB聚合框架与java驱动程序一起使用。 I don't understand how to write my request, even with this documentation . 即使有这个文档 ,我也不明白如何编写我的请求。

I want to get the 200 oldest views from all items in my collection. 我想从我的收藏中的所有项目中获取200个最旧的视图。 Here is my mongo query (which works like I want in console mode): 这是我的mongo查询(在控制台模式下工作方式如下):

db.myCollection.aggregate(
    {$unwind : "$views"},
    {$match : {"views.isActive" : true}},
    {$sort : {"views.date" : 1}},
    {$limit : 200},
    {$project : {"_id" : 0, "url" : "$views.url", "date" : "$views.date"}}
)

Items in this collection have one or many views. 此集合中的项目具有一个或多个视图。 My question is not about the request result, I want to know the java syntaxe. 我的问题不是关于请求结果,我想知道java语法。

Finally found the solution, I get the same result than with the original request. 终于找到了解决方案,我得到的结果与原始请求相同。

Mongo Driver 3 : Mongo Driver 3:

Aggregate doc 汇总文件

MongoCollection<Document> collection = database.getCollection("myCollection");

AggregateIterable<Document> output = collection.aggregate(Arrays.asList(
        new Document("$unwind", "$views"),
        new Document("$match", new Document("views.isActive", true)),
        new Document("$sort", new Document("views.date", 1)),
        new Document("$limit", 200),
        new Document("$project", new Document("_id", 0)
                    .append("url", "$views.url")
                    .append("date", "$views.date"))
        ));

// Print for demo
for (Document dbObject : output)
{
    System.out.println(dbObject);
}

You can make it more readable with static import : 您可以使用静态导入使其更具可读性:
import static com.mongodb.client.model.Aggregates.*; .
See koulini answer for complet example . 请参阅koulini回答complet示例

Mongo Driver 2 : Mongo Driver 2:

Aggregate doc 汇总文件

Iterable<DBObject> output = collection.aggregate(Arrays.asList(
        (DBObject) new BasicDBObject("$unwind", "$views"),
        (DBObject) new BasicDBObject("$match", new BasicDBObject("views.isActive", true)),
        (DBObject) new BasicDBObject("$sort", new BasicDBObject("views.date", 1)),
        (DBObject) new BasicDBObject("$limit", 200),
        (DBObject) new BasicDBObject("$project", new BasicDBObject("_id", 0)
                    .append("url", "$views.url")
                    .append("date", "$views.date"))
        )).results();

// Print for demo
for (DBObject dbObject : output)
{
    System.out.println(dbObject);
}

Query conversion logic : 查询转换逻辑: 查询转换逻辑 Thank to this link 感谢这个链接

It is worth pointing out, that you can greatly improve the code shown by the answers here, by using the Java Aggregation methods for MongoDB. 值得指出的是,通过使用MongoDB的Java聚合方法,您可以大大改善这里的答案所显示的代码。

Let's take as a code example, the OP's answer to his own question. 让我们以代码为例,OP回答他自己的问题。

AggregateIterable<Document> output = collection.aggregate(Arrays.asList(
        new Document("$unwind", "$views"),
        new Document("$match", new Document("views.isActive", true)),
        new Document("$sort", new Document("views.date", 1)),
        new Document("$limit", 200),
        new Document("$project", new Document("_id", 0)
                    .append("url", "$views.url")
                    .append("date", "$views.date"))
));

We can rewrite the above code as follows; 我们可以重写上面的代码如下;

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

AggregateIterable output = collection.aggregate(Arrays.asList(
                unwind("$views"),
                match(new Document("views.isActive",true)),
                sort(new Document("views.date",1)),
                limit(200),
                project(new Document("_id",0)
                        .append("url","$views.url")
                        .append("date","$views.date"))
));

Obviously, you will need the corresponding static import but beyond that, the code in the second example is cleaner , safer (as you don't have to type the operators yourself every time), more readable and more beautiful IMO. 显然,您将需要相应的静态导入,但除此之外,第二个示例中的代码更清晰更安全 (因为您不必每次都自己键入运算符),更可读和更美观的 IMO。

Using previous example as a guide, here's how to do it using mongo driver 3 and up: 使用前面的示例作为指南,以下是使用mongo驱动程序3及以上的方法:

MongoCollection<Document> collection = database.getCollection("myCollection");
AggregateIterable<Document> output = collection.aggregate(Arrays.asList(
    new Document("$unwind", "$views"),
    new Document("$match", new Document("views.isActive", true))
));

for (Document doc : output) {
    ...
}

Here is a simple way to count employee by departmentId.. Details at: Aggregation using Java API 这是一种通过departmentId统计员工的简单方法。详细信息: 使用Java API进行聚合

        Map<Long, Integer> empCountMap = new HashMap<>();

        AggregateIterable<Document> iterable = getMongoCollection().aggregate(Arrays.asList(
                new Document("$match",
                        new Document("active", Boolean.TRUE)
                                .append("region", "India")),
                new Document("$group",
                        new Document("_id", "$" + "deptId").append("count", new Document("$sum", 1)))));

        iterable.forEach(new Block<Document>() {
            @Override
            public void apply(final Document document) {
                empCountMap.put((Long) document.get("_id"), (Integer) document.get("count"));
            }
        });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM