我有一个名为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")
。
答案 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 } },
])