如何在Spring中编写mongo聚合减少查询? [英] How do I write mongo aggregation reduce query in Spring?

查看:153
本文介绍了如何在Spring中编写mongo聚合减少查询?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

mongo中的数据:

data in mongo :

在此处输入图片描述

db.test2.aggregate([
    {
        "$project" : {
        "contents" : 1,
        "comments" : {
            "$filter" : {
                "input" : "$comments", 
                "as" : "item", 
                "cond" : {"$gt" : ['$$item.score', 2]}

                },
            },
         "comments2" : {
            "$filter" : {
                "input" : "$comments2", 
                "as" : "item", 
                "cond" : {"$gt" : ["$$item.score", 5]}
            }
            }
        }
     },
     {
     "$project" : {
            "content" : 1,
            "commentsTotal" : {
                "$reduce" : {
                    "input" : "$comments",
                    "initialValue" : 0,
                    "in" : {"$add" : ["$$value", "$$this.score"]}
                }
                },
            "comments2Total" : {
                "$reduce" : {
                "input" : "$comments2",
                "initialValue" : 0,
                    "in" : {"$add" : ["$$value", "$$this.score"]}
                }
            }
        }
      },
      {$skip : 0},
      {$limit: 3}

  ]);
  <!-- language: lang-json-->

所以您可以看到,它执行以下操作: 1,过滤评论和评论2,得分≥5. 2,在评论数组中计算总数.

So you can see, this does the following : 1、filter the comments and comments2 which score is gt 5. 2、count total of the socre in comment array.

我这样在Spring中编写聚合查询:

and i write the aggregation query in Spring like this:

AggregationExpression reduce = ArithmeticOperators.Add.valueOf("$$value").add("$$this.socre");
    Aggregation aggregation = Aggregation.newAggregation(
            Aggregation.project().andExclude("_id")
                    .andInclude("content")
                    .and("comments").filter("item", ComparisonOperators.Gt.valueOf("item.score").greaterThanValue(3)).as("comments")
                    .and("comments2").filter("item", ComparisonOperators.Gt.valueOf("item.score").greaterThanValue(3)).as("comments2"),
            Aggregation.project("comments", "comments2")
                    .and(ArrayOperators.Reduce.arrayOf("comments").withInitialValue("0").reduce(reduce)).as("commentsTotal")
    );

当我跑起来时,它会抛出异常:

when i run like up , it will throws exception :

java.lang.IllegalArgumentException:无效的引用'$$ value'!

java.lang.IllegalArgumentException: Invalid reference '$$value'!

推荐答案

您可以通过将$filter包装在$reduce操作中来尝试以下聚合.

You can try below aggregation by wrapping $filter inside the $reduce operation.

类似下面的内容

AggregationExpression reduce1 = new AggregationExpression() {
        @Override
        public DBObject toDbObject(AggregationOperationContext aggregationOperationContext) {
         DBObject filter = new BasicDBObject("$filter", new BasicDBObject("input", "$comments").append("as", "item").append("cond",
                    new BasicDBObject("$gt", Arrays.<Object>asList("$$item.score", 2))));
         DBObject reduce = new BasicDBObject("input", filter).append("initialValue", 0).append("in", new BasicDBObject("$add", Arrays.asList("$$value", "$$this.socre")));
         return new BasicDBObject("$reduce", reduce);
     }
 };

Aggregation aggregation = newAggregation(
     Aggregation.project().andExclude("_id")
       .andInclude("content")
       .and(reduce1).as("commentsTotal")
);

这篇关于如何在Spring中编写mongo聚合减少查询?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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