如何按数组字段分组?

时间:2019-01-15 16:55:18

标签: mongodb

假设我在一个文档集中(messages)中包含以下文档:

[
    {
        _id: 1,
        message: "...",
        participants: [1, 2],
        datetime_created: ...
    },
    {
        _id: 2,
        message: "...",
        participants: [4, 9],
        datetime_created: ...
    },
    {
        _id: 3,
        message: "...",
        participants: [2, 1],
        datetime_created: ...
    },     
    {
        _id: 4,
        message: "...",
        participants: [3, 6],
        datetime_created: ...
    }
]

现在,我正在尝试获取参与者1(当前已登录用户)和参与者2之间的最后一条对话消息。我试图编写这样的聚合管道:

[
    {
        $match: {
            participants: {
                $in: [1] // logged in user
            }
        }
    },
    {
        $sort: {
            datetime_created: -1
        }
    },
    {
        $group: {
            _id: "$participants",
            last_message: {
                $first: "$$ROOT"
            }
        }
    }
]

它有效,但不完全。问题是$groupparticipants的使用方式使得[1, 2][2, 1]被认为是不同的元素,因为数组是数据的有序集合。是否有仅MongoDB的方式可以忽略数组中的顺序?

一个解决方案是在数据插入过程中对participants进行排序,这是可行的,但我宁愿有一个仅在数据库端有效的解决方案。

1 个答案:

答案 0 :(得分:1)

您可以使用以下汇总

[
  { "$match": { "participants": { "$in": [1] }}},
  { "$unwind": "$participants" }
  { "$sort": { "participants": 1 }},
  { "$group": {
    "_id": "$_id",
    "participants": { "$push": "$participants" },
    "message": { "$first": "$message" },
    "datetime_created": { "$first": "$datetime_created" },
  }},
  { "$sort": { "datetime_created": -1 }},
  { "$group": {
    "_id": "$participants",
    "last_message": { "$first": "$$ROOT" }
  }}
]