如何过滤对象数组以根据 MongoDB 聚合中的条件删除元素?

How to filter an array of objects to remove elements based on condition in MongoDB aggregate?

我在 MongoDB 中有一组文档 ChatRooms 具有以下(简化)结构:

{
  _id: ObjectId('4654'),
  messages: [
    {
      user: ObjectId('1234'),
      sentAt: ISODate('2022-03-01T00:00:00.000Z')
    },
    {
      user: ObjectId('1234'),
      sentAt: ISODate('2022-03-02T00:00:00.000Z')
    },
    {
      user: ObjectId('8888'),
      sentAt: ISODate('2022-03-03T00:00:00.000Z')
    },
  ]
}

我想要实现的是过滤 aggregate 管道内的 messages 数组,以获得 userId 只存在一次的数组。我正在寻找的结果是(或类似的东西,但数组不应该有两个具有相同 user id 的元素):

{
  _id: ObjectId('4654'),
  messages: [
    {
      user: ObjectId('1234'),
      sentAt: ISODate('2022-03-01T00:00:00.000Z')
    },
    {
      user: ObjectId('8888'),
      sentAt: ISODate('2022-03-03T00:00:00.000Z')
    },
  ]
}

这种事情有可能吗? 任何帮助将不胜感激。

您可以通过几种不同的方式做到这一点,这里是一个如何使用 $reduce 运算符实现这一点的示例:

db.collection.aggregate([
  {
    $addFields: {
      messages: {
        $reduce: {
          input: "$messages",
          initialValue: [],
          in: {
            $cond: [
              {
                $in: [
                  "$$this.user",
                  "$$value.user"
                ]
              },
              "$$value",
              {
                "$concatArrays": [
                  "$$value",
                  [
                    "$$this"
                  ]
                ]
              }
            ]
          }
        }
      }
    }
  }
])

Mongo Playground