在MongoDb中按深层文档字段排序

时间:2019-03-27 16:38:00

标签: arrays mongodb aggregation-framework

我有一个名为Visitor的集合,该集合具有一个聊天数组,每个数组都有一个名为user的文档。
我需要在此收藏夹中找到一些文档,如果他们的聊天中首先有特定用户,则对它们进行排序。

用户ID的路​​径为:
chats.user._id

其中:

chats // array
  user // document
    _id // ObjectId

下面的脚本可以正确地对文档进行排序,但是,它扩展了chats数组,并为数组中的每个chat乘以文档。

我只需要排序,是否可以排序而不使用unwind管道,或者使其不以某种方式乘以文档?

db.getCollection('Visitor').aggregate([
{$unwind: "$chats"},
{ $match: {'event._id':ObjectId('5c942a3591deb389bfd92579'), 'chats.enabled': {$exists: true}}},
{ 
    "$project": {
        "_id": 1,
        "chats.user._id": 1,
        "weight": {
            "$cond": [
                { "$eq": [ "$chats.user._id", ObjectId("5c942a3591deb389bfd92579") ] },
                10,
                0
            ]
        }
    }
},
{ "$sort": { "weight": -1 } },
])

编辑:我不需要对内部数组进行排序,而是通过检查特定用户是否在chats数组中对find命令进行排序。

一些游客收藏品样本:

[
{
    "_id" : ObjectId("5c9a3a1bd86e0ba64106e90e"),
    "event" : {
        "_id" : ObjectId("5c942a3591deb389bfd92579")
    },
    "chats" : [ 
        {
            "enabled" : false,
            "user" : {
                "_id" : ObjectId("5c81232f09a923b559763418")
            },
            "_id" : ObjectId("5c9a3a1bd86e0ba64106e915")
        }
    ]
},
{
    "_id" : ObjectId("5c9a3a35d86e0ba64106e950"),
    "event" : {
        "_id" : ObjectId("5c942a3591deb389bfd92579")
    },
    "chats" : [ 
        {
            "enabled" : true,
            "user" : {
                "_id" : ObjectId("5c81232f09a923b559763418")
            },
            "_id" : ObjectId("5c9a3a35d86e0ba64106e957")
        }, 
        {
            "enabled" : true,
            "user" : {
                "_id" : ObjectId("5c942a3591deb389bfd92579")
            },
            "_id" : ObjectId("5c9a3a34d86e0ba64106e91d")
        }
    ]
}
]

在上面的示例中,我需要使第二个文档首先进行排序,因为它的用户具有_id ObjectId("5c942a3591deb389bfd92579")

1 个答案:

答案 0 :(得分:1)

这里的问题是,使用$ unwind可以修改文档的初始结构(每个chats您将获得一个文档。我建议使用$map获取基于指定userId的权重数组然后您可以使用$max获得最终的weight

db.col.aggregate([
    { $match: {'event._id':ObjectId('5c942a3591deb389bfd92579'), 'chats.enabled': {$exists: true}}},
    { 
        "$project": {
            "_id": 1,
            "chats.user._id": 1,
            "weight": {
                $max: { $map: { input: "$chats", in: { $cond: [ { $eq: [ "$$this.user._id", ObjectId("5c942a3591deb389bfd92579") ] }, 10, 0  ] } } }
            }
        }
    },
    { "$sort": { "weight": -1 } },
])