我正在寻找一种对嵌套对象数组进行排序的方法。
这是一个例子:
{
answers : [
{ name : 'paul', state : 'RU' },
{ name : 'steve', state : 'US' },
{ name : 'mike', state : 'DE' },
...
]
}
假设现在我想找到数组的所有name
, answers
,但我怎样才能按升序对它们进行排序呢?
我会按照你想要的顺序存储它。或者在您将其拉出后,在客户端对其进行排序。
如果这些都不可能,您可以使用聚合框架:
> db.test.insert({answers: [
... {name: 'paul', state: 'RU'},
... {name: 'steve', state: 'US'},
... {name: 'mike', state: 'DE'}]});
> db.test.insert({answers: [
... {name: 'paul', state: 'RU'},
... {name: 'steve', state: 'US'},
... {name: 'xavier', state: 'TX'}]});
db.test.aggregate([
{$unwind: "$answers"},
{$sort: {"answers.name":1}},
{$group: {_id:"$_id", answers: {$push:"$answers"}}}
]);
产生:
{
"result" : [
{
"_id" : ObjectId("5053b2477d820880c3469364"),
"answers" : [
{
"name" : "paul",
"state" : "RU"
},
{
"name" : "steve",
"state" : "US"
},
{
"name" : "xavier",
"state" : "TX"
}
]
},
{
"_id" : ObjectId("5053af9f7d820880c3469363"),
"answers" : [
{
"name" : "mike",
"state" : "DE"
},
{
"name" : "paul",
"state" : "RU"
},
{
"name" : "steve",
"state" : "US"
}
]
}
],
"ok" : 1
}
这在这种情况下可能没有帮助,但我想我会添加这个。您还可以选择在写入时对其进行排序,这对于您不必以多种方式排序的非规范化集合往往更好。
在为用户创建提要时,我在我的应用程序中发现了这种情况。
Meteor.users.helpers({
'addToFeed': function (gameId, pushData) {
check(pushData, FeedSchema);
Meteor.users.update({
_id: this._id,
"games.gameId": gameId
}, {
$push: {
"games.$.feed": {
$each: [pushData],
$sort: { timestamp: -1 }
}
}
});
}
});
我发现它非常方便,因为您可以使用find()
它,默认情况下它会按您的规格排序。
从 开始Mongo 4.4
,$function
聚合运算符允许应用自定义 javascript 函数来实现 MongoDB 查询语言不支持的行为。
例如,为了按其中一个字段对对象数组进行排序:
// {
// "answers" : [
// { "name" : "steve", "state" : "US" },
// { "name" : "xavier", "state" : "FR" },
// { "name" : "paul", "state" : "RU" }
// ]
// }
db.collection.aggregate(
{ $set:
{ "answers":
{ $function: {
body: function(answers) { return answers.sort((a, b) => a.name > b.name); },
args: ["$answers"],
lang: "js"
}}
}
}
)
// {
// "answers" : [
// { "name" : "paul", "state" : "RU" },
// { "name" : "steve", "state" : "US" },
// { "name" : "xavier", "state" : "FR" }
// ]
// }
这会在适当的位置修改数组,而无需应用昂贵$unwind
的$sort
和$group
阶段的组合。
$function
接受3个参数:
body
,这是要应用的函数,其参数是要修改的数组。args
,其中包含body
函数作为参数的记录中的字段。在我们的例子"$answers"
中。lang
,这body
是编写函数的语言。仅js
当前可用。我在更新嵌套数组时找到了一个解决方案,我们也可以对其进行排序,更新后我们将有一个排序数组,然后我们不需要在 find 上排序
db.students.update(
{ _id: 1 },
{
$push: {
quizzes: {
$each: [ `enter code here`{ id: 3, score: 8 }, { id: 4, score: 7 }, { id: 5, score: 6 } ],
$sort: { score: 1 }
}
}
}
)
执行 find() 后,您可以在返回值上使用 sort()。
db.collection.find({},{"answers.name":1}).sort({"answers.name":1})
该查找将提取集合中所有文档的名称字段。然后排序将按名称对它们进行升序排序。
http://www.mongodb.org/display/DOCS/Sorting+and+Natural+Order