Mongodb 在数组和子数组中使用$size和$sort

Mongodb 在数组和子数组中使用$size和$sort,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,以下是我收藏的结构部分: _id: ObjectId("W"), names: [ { number: 1, subnames: [ { id: "X", day: 1 }, { id: "Y", day: 10 }, { id: "Z", day: 2 } ], list: ["A","B","C"], day: 1 }, { number: 2, day: 5 },

以下是我收藏的结构部分:

_id: ObjectId("W"),
names: [
    {
        number: 1,
        subnames: [ { id: "X", day: 1 }, { id: "Y", day: 10 }, { id: "Z", day: 2 } ],
        list: ["A","B","C"],
        day: 1
    },
    {
        number: 2,
        day: 5
    },
    {
        number: 3,
        subnames: [ { id: "X", day: 8 }, { id: "Z", day: 5 } ],
        list: ["A","C"],
        day: 2
    },
    ...
],
...
我使用此请求:

db.publication.aggregate( [ { $match: { _id: ObjectId("W") } }, { $group: { _id: "$_id", SizeName: { $first: { $size: { $ifNull: [ "$names", [] ] } } }, names: { $first: "$names" } } }, { $unwind: "$names" }, { $sort: { "names.day": 1 } }, { $group: { _id: "$_id", SzNames: { $sum: 1 }, names: { $push: { number: "$names.number", subnames: "$names.subnames", list: "$names.list", SizeList: { $size: { $ifNull: [ "$names.list", [] ] } } } } } } ] );
但是我现在会对我的名称数组和我的子名称数组使用$sort来获得这个结果(子名称可能不存在):


你能帮我吗?

你能做到,但难度很大。作为一个例子,我很乐意投票支持一个内联版本的操作系统。这会让事情变得容易得多

不过,现在您需要在排序后重新构建数组。你必须非常小心。因此,在处理前使用单个条目生成假数组:

db.publication.aggregate([
{“$project”:{
“SizeNames”:{
“$size”:{
“$ifNull”:[“$names”,[]
}
},
“名称”:{“$ifNull”:[{“$map”:{
“输入”:“$names”,
“as”:“el”,
“在”:{
“SizeList”:{
“$size”:{
“$ifNull”:[“$$el.list”,[]
}
},
“大小子名称”:{
“$size”:{
“$ifNull”:[“$$el.subnames”,[]
}
},
“编号”:“$$el.number”,
“日”:“$$el.day”,
“子名称”:{“$ifNull”:[“$$el.subnames”,[0]},
“列表”:“$$el.list”
}
}}, [0] ] }
}},
{“$unwind”:“$NAME”},
{“$unwind”:“$names.subnames”},
{“$sort”:{“_id”:1,“name.subnames.day”:1},
{“$组”:{
“_id”:{
“\u id”:“$\u id”,
“SizeNames”:“$SizeNames”,
“姓名”:{
“SizeList”:“$names.SizeList”,
“SizeSubnames”:“$names.SizeSubnames”,
“编号”:“$names.number”,
“列表”:“$names.list”,
“日”:“$names.day”
}
},
“子名称”:{“$push”:“$names.subnames”}
}},
{“$sort”:{“\u id.\u id”:1,“\u id.names.day”:1}},
{“$组”:{
“\u id”:“$\u id.\u id”,
“SizeNames”:{“$first”:“$\u id.SizeNames”},
“姓名”:{
“$push”:{“$cond”:[
{“$ne”:[“$\u id.names.SizeSubnames”,0]},
{
“编号”:“$\u id.names.number”,
“子名称”:“$subnames”,
“列表”:“$\u id.names.list”,
“SizeList”:“$\u id.names.SizeList”,
“日期”:“$\u id.names.day”
},
{
“编号”:“$\u id.names.number”,
“列表”:“$\u id.names.list”,
“SizeList”:“$\u id.names.SizeList”,
“日期”:“$\u id.names.day”
}
]}
}
}},
{“$project”:{
“SizeNames”:1,
“姓名”:{
“$cond”:[
{“$ne”:[“$SizeNames”,0]},
“$names”,
[]
]
}
}}
])
您可以从内部文档中“隐藏”原始空数组,如图所示,但是如果不使用类似的条件数组“推送”技术,就很难删除外部“名称”数组的所有存在,这确实是一种不实用的方法

但是,如果所有这些都只是对单个文档中的数组元素进行排序,那么聚合框架就不应该是这样做的工具。它可以如图所示完成,但对于每个文档来说,这在客户端代码中要容易得多

输出:

{
“_id”:ObjectId(“54b5cff8102f29253ce9bb5”),
“SizeNames”:3,
“姓名”:[
{
“数字”:1,
“子名称”:[
{
“id”:“X”,
“天”:1
},
{
“id”:“Z”,
“天”:2
},
{
“id”:“Y”,
“天”:10
}
],
“名单”:[
“A”,
“B”,
“C”
],
“SizeList”:3,
“天”:1
},
{
“数字”:3,
“子名称”:[
{
“id”:“Z”,
“天”:5
},
{
“id”:“X”,
“天”:8
}
],
“名单”:[
“A”,
“C”
],
“SizeList”:2,
“天”:2
},
{
“数字”:2,
“SizeList”:0,
“天”:5
}
]
}

这只是一个友好的提示。在撰写您的个人资料时,您尚未接受任何问题的答案。好的,对不起,我只是看到了它,是否要在所有子名称文档中添加SizeX(带$size)?你能帮忙吗me@JohnS当然我可以,而且很可能其他人也会做出贡献。但这是如何运作的,你需要“问一个新问题”,包括你真正想要的所有细节。然后你“接受”给你的答案,正如我已经提示过的。一个问题,一个答案。这就是它的工作原理。欢迎来到StackOverflow。
_id: ObjectId("W"),
names: [
    {
        number: 2,
        SizeList: 0,
        day: 5
    },
    {
        number: 3,
        subnames: [ { id: "Z", day: 5 }, { id: "X", day: 8 } ],
        list: ["A","C"],
        SizeList: 2,
        day: 2
    },
    {
        number: 1,
        subnames: [ { id: "X", day: 1 }, { id: "Z", day: 2 }, { id: "Y", day: 10 } ],
        list: ["A","B","C"],
        SizeList: 3,
        day: 1
    }
    ...
],
...