当前位置: 首页 > 知识库问答 >
问题:

带条件的mongotemplate聚合

萧繁
2023-03-14

我有一个集合,其中的文档如下所示:

{
  _id: "545b9fa0dd5318a4285f7ce7",
  owner: "admin",  
  messages: [
    {
      id: "100",
      status: "sent",
      note: ""
    },
    {
      id: "100",
      status: "pending",
      note: ""
    },
    {
      id: "101",
      status: "sent",
      note: ""
    },
    {
      id: "102",
      status: "sent",
      note: ""
    },
    {
      id: "101",
      status: "done",
      note: ""
    }
  ]
}
{
   sent: 3,
   pending: 1,
   done: 1
}

共有1个答案

朱锦
2023-03-14

要执行这种操作,您需要在聚合框架中使用$cond运算符。Spring Data MongoDB还没有做到这一点,公共的$group操作缺少很多东西,这些操作甚至只在$project下实现。

跟踪任何$cond支持的实现的问题是:

https://jira.spring.io/browse/datamongo-861

db.collection.aggregate([
    { "$match": { "_id": ObjectId("545b9fa0dd5318a4285f7ce7") } },
    { "$unwind": "$messages" },
    { "$group": {
        "_id": "$_id",
        "sent": {
            "$sum": {
                "$cond": [
                    { "$eq": [ "$mesages.status", "sent" ] },
                    1,
                    0
                ]
            }
        },
        "pending": {
            "$sum": {
                "$cond": [
                    { "$eq": [ "$messages.status", "pending" ] },
                    1,
                    0
                ]
            }
        },
        "done": {
            "$sum": {
                "$cond": [
                    { "$eq": [ "$messages.status", "done" ] },
                    1,
                    0
                ]
            }
        }
    }}
])
public class CustomGroupOperation implements AggregationOperation {
    private DBObject operation;

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

    @Override
    public DBObject toDBObject(AggregationOperationContext context) {
        return context.getMappedObject(operation);
    }
}
   DBObject myGroup = (DBObject)new BasicDBObject(
        "$group", new BasicDBObject(
            "_id","$_id"
        ).append(
            "sent", new BasicDBObject(
                "$sum", new BasicDBObject(
                    "$cond", new Object[]{
                        new BasicDBObject(
                            "$eq", new Object[]{ "$messages.status", "sent"}
                        ),
                        1,
                        0
                    }
                )
            )
        ).append(
            "pending", new BasicDBObject(
                "$sum", new BasicDBObject(
                    "$cond", new Object[]{
                        new BasicDBObject(
                            "$eq", new Object[]{ "$messages.status", "pending"}
                        ),
                        1,
                        0
                    }
                )
             )
        ).append(
            "done", new BasicDBObject(
                "$sum", new BasicDBObject(
                    "$cond", new Object[]{
                         new BasicDBObject(
                            "$eq", new Object[]{ "$messages.status", "done"}
                         ),
                         1,
                         0
                    }
                 )
            )
        )
     );


   ObjectId myId = new ObjectId("545b9fa0dd5318a4285f7ce7");

   Aggregation aggregation = newAggregation(
           match(Criteria.where("_id").is(myId)),
           unwind("messges"),
           new CustomGroupOperation(myGroup)
   );

这允许您提出一个与上面的shell表示形式基本相同的管道。

因此,就目前而言,在某些操作和序列不受支持的情况下,最好的情况是在AgggregationOperation接口上实现一个类,该类可以被提供给DBObject,或者从您自己的自定义方法内部构造一个类。

 类似资料:
  • 我使用的是Spring Boot+MongoDB。我需要根据一些条件查询数据库,我的方法如下所示: org.bson.bsonmaximumsizeExprocededException:文档大小46282052大于最大值16793600 有人能帮我做这个吗?

  • 我是Spring Boot和MongoDb的新手。尝试使用Mongo存储库和Spring Boot的一些示例。但在浏览了一些文档后发现,Mongo模板是一个更好的选择。无法使用Mongo模板示例获得正确的Spring Boot。 > 有人能帮我举个同样的例子吗? 在尝试Mongo模板时,我们是否需要创建用户定义的存储库界面并扩展存储库或CRUD存储库?

  • 我试图开发以下过滤器与熊猫数据帧: 我有四列,,,和 如何将其作为聚合函数编写? 下面是一个编写效率低下的工作示例: 输出:

  • 我正在寻找一种基于消息聚合的有条件处理消息的方法。我已经研究了很多方法来实现这一点,但似乎Apache Camel不支持它。我会解释这个场景,然后解释我尝试的解决方案。 我试图再次获取文件来处理它们。问题是,据我所知,你不能让消费者按需购买。我尝试使用pollenfrice,但它只能获取单个文件,而不是目录中的所有文件。 我试图筛选/停止父路由。这里的问题是filter()/choice...st

  • 我想使用条件查询。 这是我的问题 这是我的java代码 它给出

  • 给定具有以下文档的集合: 假设有更多的这些文档带有其他“resource-id”值,我希望返回我之前键入的同一个文档,但是“mappings”数组只包含version-tag=X的对象,“address-aggregations”数组只包含[pidx,pidy,...]中带有“pid”的对象。我目前能想到的最好的方法是以下聚合管道: 它在mongodb客户端shell上返回了预期的结果。但是,当我