【问题标题】:Way to write a aggregation query with a divide operation on size array in projection使用投影中大小数组的除法操作编写聚合查询的方法
【发布时间】:2015-05-19 21:25:41
【问题描述】:

我想使用 Spring Data MongoDB 运行这个聚合查询。

db.collectionname.aggregate(
   {
        "$group": {
        "_id": "$searchTerm",
        "dateAddToSet": {
            "$addToSet": "$date"
        }
    }
  },
  {
    "$project": {
        "searchTerm": "$_id.searchTerm",
        "percent": {
            "$divide": [{ "$size": "$dateAddToSet" }, 28]
        }
    }
  })

我找不到在 $dataAddToSet 大小上编写除法操作以执行此查询的方法。

非常感谢。

【问题讨论】:

  • 一点建议。如果您一开始就写了一份有效的声明,那将对您的事业有所帮助。只有{ "$divide": [{ "$size": "$dateAddToSet"}, 28 ] } 在这里有效。包装数组会导致错误。或者至少是 1 的无效值
  • 感谢您的回复。此查询工作正常并返回给我一个很好的结果。但你是对的,我会编辑我的查询...

标签: java mongodb mongodb-query aggregation-framework spring-data-mongodb


【解决方案1】:

抱歉耽搁了。这里的主要问题是 $size 目前在 spring mongo 中不是受支持的操作。所以构造操作的唯一方法是使用 DBObject 构造。

但是您可以通过提供自己的包装类来混合这两种方法,例如:

public class CustomAggregationOperation implements AggregationOperation {
    private DBObject operation;

    public CustomAggregationOperation (DBObject operation) {
        this.operation = operation;
    }

    @Override
    public DBObject toDBObject(AggregationOperationContext context) {
        return context.getMappedObject(operation);
    }
}

所以通常重写.toDBObject() 方法,只返回提供给类的构造函数的DBObject 数据。

然后在构建聚合时使用:

    Aggregation agg = newAggregation(
            group("searchTerm")
                    .addToSet("date").as("dateAddToSet"),
            new CustomAggregationOperation(
                new BasicDBObject("$project",
                    new BasicDBObject("_id",0)
                        .append("searchTerm","$_id")
                        .append("percent",new BasicDBObject(
                                "$divide", new Object[]{
                                    new BasicDBObject("$size","dateAddToSet"),
                                    28
                                }

                            )
                        )
                )
            )
    );

这会产生一个格式正确的管道:

{ 
    "aggregate" : "__collection__" , 
    "pipeline" : [ 
        { "$group" : { 
            "_id" : "$searchTerm" , 
            "dateAddToSet" : { "$addToSet" : "$date" }
        }}, 
        { "$project" : { 
            "_id" : 0 ,
            "searchTerm" : "$_id" , 
            "percent" : { "$divide" : [ { "$size" : "$dateAddToSet" } , 28] }
        }}
    ]
}

因此,这是将可用构建器与自定义构造混合在一起的一种方法,这样您就可以使用当前不存在构建器的方法。

【讨论】:

  • 非常感谢。你的回答对我帮助很大。我不知道这种方式来自定义我的聚合查询。我现在就实施!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多