如何在MongoDB中使用聚合按计数元素分组?

at0kjp5o  于 2023-10-16  发布在  Go
关注(0)|答案(1)|浏览(121)

我必须使用MQL编写一些聚合。案例是:
1.有一个聊天应用程序
1.集合包含以下信息:线程、发送消息、发送时间、读取时间
样本记录如下所示。

留言_收藏

[
    {
      "thread" : "war conference",
      "message" : "stop",
      "sentInMilli": 1696858510000, // oldest message in war conference
      "statuses": [ {"readInMilli": 1696858547857} ]
    },
    {
      "thread" : "economic conference",
      "message" : "welcome on economic conference",
      "sentInMilli": 1696858520000, // newest message in economic conference
      "statuses": [ {"readInMilli": 1696858547857} ]
    },
    {
      "thread" : "war conference",
      "message" : "the war",
      "sentInMilli": 1696858530000, // newest message in war conference
      "statuses": [ ]
    }
]

我想做的是显示关于线程的数据。更具体地说,我需要知道哪些线程有未读消息。正如你在上面的例子中看到的,有两个线程:war conferenceeconomic conference
所以在我的假设聚合之后,我想得到这样的记录:

[
  {
    "thread": "war conference",
    "timeInMilliOfNewestMessage": 1696858530000,
    "containsUnreadMessages": true
  },
  {
    "thread": "economic conference",
    "timeInMilliOfNewestMessage": 1696858520000,
    "containsUnreadMessages": false
  }
]

我当前的伪查询:

db.getCollection('message_collection').aggregate(
    [
        {
            "$match": { } // my other conditions...
        },
        {
            "$group": {
                "_id": "thread", 
                "timeInMilliOfNewestMessage": {"$max": "$sentInMilli"},
                "containsUnreadMessages": { 
                    "$count": {
                        "statuses": {
                            "$elemMatch": {
                                "readInMilli": { "$exists": false }
                            } 
                        }
                    }
                }
            }
        }
    ]
)

正如你所看到的,我有一个想法,首先计算所有已经阅读的消息。然后我想把它转换成布尔值。
我得到了这个错误:

Unrecognized expression '$elemMatch'

我知道这个语法是无效的,但我不知道为什么:
也许我想达到的目标在小组赛中是不可能实现的?
有人能帮我吗?

db.version()
4.0.0
but5z9lq

but5z9lq1#

当您使用MongoDB v4.0+时,可能的解决方案之一是$min数组大小statuses,并检查它是否为0

db.collection.aggregate([
  {
    "$group": {
      "_id": "$thread",
      "timeInMilliOfNewestMessage": {
        "$max": "$sentInMilli"
      },
      "containsUnreadMessages": {
        "$min": {
          $size: "$statuses"
        }
      }
    }
  },
  {
    "$addFields": {
      "containsUnreadMessages": {
        "$cond": {
          "if": {
            $eq: [
              "$containsUnreadMessages",
              0
            ]
          },
          "then": true,
          "else": false
        }
      }
    }
  }
])

Mongo Playground

相关问题