【问题标题】:MongoDB aggregation with Java driver带有 Java 驱动程序的 MongoDB 聚合
【发布时间】:2015-07-26 23:43:11
【问题描述】:

在将 MongoDB 聚合框架与 java 驱动程序结合使用时,我需要您的帮助。 我不明白如何写我的请求,即使是this documentation

我想从我的收藏中的所有项目中获取 200 个最旧的视图。这是我的 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"}}
)

此集合中的项目具有一个或多个视图。 我的问题不是请求结果,我想知道java语法。

【问题讨论】:

  • 向我们展示您现在尝试的内容,如果它不起作用。不要指望 SO 为您编写代码

标签: java mongodb aggregation-framework


【解决方案1】:

终于找到了解决方案,我得到了和原来请求一样的结果。

Mongo 驱动程序 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);
}

您可以通过静态导入使其更具可读性:
import static com.mongodb.client.model.Aggregates.*;.
koulini answer for complet example

Mongo 驱动程序 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);
}

查询转换逻辑: 感谢this link

【讨论】:

  • 您使用的是哪个文档,我使用的是 Mongo 驱动程序 3.4,在这个类中:com.mongodb.DBCollection,只有聚合函数使用 DBObject 而不是文档? => public AggregationOutput 聚合(最终列表 管道)
  • 这是来自com.mongodb.async.clientMongoCollection。方法在哪里:aggregate(List&lt;? extends Bson&gt; pipeline)。而Document 实现了Bson,所以一切都很好。
  • 你拯救了我的一天。
【解决方案2】:

值得指出的是,通过使用 MongoDB 的 Java 聚合方法,您可以大大改进此处答案显示的代码。

让我们以代码示例为例,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"))
));

我们可以将上面的代码改写如下;

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"))
));

显然,您将需要相应的静态导入,但除此之外,第二个示例中的代码是 cleanersafer(因为您不必键入每次都自己操作),更可读和更美丽 IMO。

【讨论】:

    【解决方案3】:

    使用前面的示例作为指导,以下是使用 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) {
        ...
    }
    

    【讨论】:

      【解决方案4】:

      这是一种按部门 ID 计算员工人数的简单方法。 详情在:Aggregation using 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"));
                  }
              });
      

      【讨论】:

        猜你喜欢
        • 2016-02-11
        • 2016-08-03
        • 2012-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多