【问题标题】:Sort by deep document field in MongoDb按 MongoDb 中的深层文档字段排序
【发布时间】:2019-03-28 00:48:20
【问题描述】:

我有一个名为 Visitor 的集合,其中有一个聊天数组,每个数组都有一个名为 user 的文档。
我需要在此集合中找到一些文档,并首先根据他们的聊天中是否有特定用户对它们进行排序。

用户id的路径是:
chats.user._id

在哪里:

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

以下脚本确实对文档进行了正确排序,但是,它扩展了聊天数组并将数组中每个聊天的文档相乘。

我只需要排序,所以我可以排序而不使用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")

【问题讨论】:

  • 您能否展示您收藏中的示例文档?
  • 添加了两个文档,第二个文档应该先出现@mickl

标签: arrays mongodb aggregation-framework


【解决方案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 } },
])

【讨论】:

  • 如果有一个列表用户而不是一个对象用户,您能否添加一个示例?就像它是一个聊天数组和嵌套的用户数组,然后是一些 ID
  • @Jonathan 你需要双重 $map$max 然后。如果您仍然需要帮助,请尝试并打开另一个问题,我稍后会尝试查看
猜你喜欢
  • 1970-01-01
  • 2020-09-08
  • 2015-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-07
  • 2019-11-03
相关资源
最近更新 更多