Spring Data MongoDB中的聚合总和 [英] Aggregation sum in Spring Data MongoDB

查看:546
本文介绍了Spring Data MongoDB中的聚合总和的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have MongoDB Page and Post collections. Each page document has field postIds which is array of post Ids (String objects). I want to use aggregation to count number of posts (=number of elements in array postIds) for each page. I wrote Mongo Shell aggregation function which returns exactly what I want:

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个帖子,

This means that page with id 3 has 3 posts, and page with id 2 has 3 posts as well, which is correct.

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

Now I wanted to write same using Spring MongoDB Aggregation, and wrote this simple JUnit test:

    /**
     * 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查询:

However, this aggregation query returns this native Mongo query:

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

2014-08-13 20:06:07,949 DEBUG [org.springframework.data.mongodb.core.MongoTemplate] - Executing aggregation:

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

问题: 1.如您所见,其差额是$ sum值$ 1.我需要传递数字1而不是$ 1,但我不确定如何传递. 2.我需要在这里进行项目运营吗?

Questions: 1. As you can see, the difference is with the $sum value of $1. I need to pass there number 1 instead of $1, but I am not sure how. 2. Do I need project operation here?

谢谢

推荐答案

我终于弄清楚了.关键是在Spring Data for MongoDB中使用count()聚合函数,该函数转换为在本机Mongo Shell中以1为增量的总和.这是我最后的JUnit测试:

I have figured this out finally. The key is to use count() aggregation function in Spring Data for MongoDB, which translates to sum increments by 1 in native Mongo shell. This is my final JUnit Test:

    /**
     * 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;
    }

所以最终,这转化为以下本机聚合操作:

So finally this translates to following native aggregation operation:

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

这篇关于Spring Data MongoDB中的聚合总和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆