mongodb - Spring Data MongoDB 中的聚合总和

标签 mongodb spring-data spring-data-mongodb

我有 MongoDB Page 和 Post 集合。每个页面文档都有字段 postIds,它是帖子 ID(字符串对象)的数组。我想使用聚合来计算每个页面的帖子数(= 数组 postIds 中的元素数)。我写了 Mongo Shell 聚合函数,它返回我想要的:

db.page.aggregate([
    {$unwind : '$postIds'},
    {$group : {_id: '$_id', 'sum': { $sum: 1}}}
])

它返回这个结果:

{ "_id" : "3", "sum" : 3 }
{ "_id" : "2", "sum" : 3 }

这意味着 id 为 3 的页面有 3 个帖子,id 为 2 的页面也有 3 个帖子,这是正确的。

现在我想使用 Spring MongoDB 聚合编写相同的代码,并编写了这个简单的 JUnit 测试:

    /**
     * Test page posts count
     */
    @Test
    public void testPagePostsCount() throws Exception{
        MongoTemplate template = repository.getMongoTemplate();
        Page page = new Page();
        page.setPageId("2210");
        page.setUserId("azec");
        List<String> postList = new ArrayList<String>();
        postList.add("53eb1a560efbe048c7ea698d");
        postList.add("53eb1a6b0efbe048c7ea698e");
        page.setPostIds(postList);
        template.save(page);

        Aggregation agg = newAggregation(
            match(Criteria.where("pageId").is("2210")),
            unwind("postIds"),
            group("_id").sum("1").as("sum")
            //project("$sum").and("pageId").previousOperation()
        );

        AggregationResults<PostCount> results = template.aggregate(agg, "page", PostCount.class);
        List<PostCount> postCount = results.getMappedResults();

        System.out.println("Done!");
    }

但是,此聚合查询返回此原生 Mongo 查询:

2014-08-13 20:06:07,949 DEBUG [org.springframework.data.mongodb.core.MongoTemplate] - 执行聚合:

{
   "aggregate":"page",
   "pipeline":[
      {
         "$match":{
            "pageId":"2210"
         }
      },
      {
         "$unwind":"$postIds"
      },
      {
         "$group":{
            "_id":"$_id",
            "sum":{
               "$sum":"$1"
            }
         }
      }
   ]
}

问题: 1. 如您所见,差异在于 $1 的 $sum 值。我需要传递 1 号而不是 1 美元,但我不确定如何传递。 2、这里需要项目运营吗?

谢谢

最佳答案

我终于明白了。关键是在 MongoDB 的 Spring Data 中使用 count() 聚合函数,它在 native Mongo shell 中转换为加 1 的总和增量。这是我最后的 JUnit 测试:

    /**
     * Test page posts count
     */
    @Test
    public void testPagePostsCount() throws Exception{
        MongoTemplate template = repository.getMongoTemplate();
        Page page = new Page();
        page.setPageId("2210");
        page.setUserId("azec");
        List<String> postList = new ArrayList<String>();
        postList.add("53eb1a560efbe048c7ea698d");
        postList.add("53eb1a6b0efbe048c7ea698e");
        page.setPostIds(postList);
        template.save(page);

        Aggregation agg = newAggregation(
            match(Criteria.where("_id").is("2210")),
            unwind("postIds"),
            group("_id").count().as("nPosts"),
            project("nPosts").and("_id").as("pageId")
        );

        AggregationResults<PostCount> results = template.aggregate(agg, "page", PostCount.class);
        List<PostCount> postCount = results.getMappedResults();
        Assert.assertTrue(!postCount.isEmpty());
        Assert.assertTrue(postCount.get(0).nPosts == 2);
        Assert.assertTrue(postCount.get(0).pageId.equals("2210"));
    }

    private class PostCount {
        String pageId;
        int nPosts;
    }

所以最后这转化为以下 native 聚合操作:

{
   "aggregate":"page",
   "pipeline":[
      {
         "$match":{
            "_id":"2210"
         }
      },
      {
         "$unwind":"$postIds"
      },
      {
         "$group":{
            "_id":"$_id",
            "nPosts":{
               "$sum":1
            }
         }
      },
      {
         "$project":{
            "nPosts":1,
            "pageId":"$_id"
         }
      }
   ]
}

关于mongodb - Spring Data MongoDB 中的聚合总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25293530/

相关文章:

mongodb - Silex 和 MongoDB,其中 Silex Extension

javascript - 前一个查询的 meteor 返回名称

java - 以编程方式设置 MongoDb 转换器

java - spring data mongorepository.save E11000 有时出现重复键错误索引

spring-mvc - Spring 和 MongoDB : Saving Value Objects in a more flat way

javascript - 为什么我不能增加 mongoose/mongodb ?

java - MongoSink 响应后提交给 kafka 消费者 - alpakka mongo 连接器

java - 从另一个角度提问

java - 在 Spring Data Commons 2.0.4 中找不到 QueryDslPredicateExecutor

spring - @CreatedBy 和 @LastModifiedDate 不再与 ZonedDateTime 一起使用?