java - 如何在 Spring 中编写 mongodb 聚合减少查询?

标签 java spring mongodb

mongo 中的数据:

enter image description here

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、筛选评分为gt 5的评论和评论2。 2、统计评论数组中socre的总数。

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

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

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

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

最佳答案

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

类似下面的内容

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

关于java - 如何在 Spring 中编写 mongodb 聚合减少查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45009103/

相关文章:

javascript - mongodb -- count() 比 find() 慢多少?

java - netbeans,无法部署Web项目

java - 在多个地方配置 Spring Security

spring - SpringBoot中无法解析ServletRegistrationBean

MongoDB 触发引用更新

java - Java Node 类中的DeleteNode 放在哪里?

java - 延迟访问服务器以尽量避开高峰时间

java - 无法使用 jdbc 数据源配置 Spring Security

java - Velocity 宏与指令

javascript - PUT 方法出错。 AngularJS、NodeJS