我正在寻找一种对嵌套的对象数组进行排序的方法。这是一个例子:
answers: [
{name: 'paul', state: 'RU'},
{name: 'steve', state: 'US'},
{name: 'mike', state: 'DE'},
...
]
现在假设我想查找name
数组的所有answers
,但是按升序排序,我该如何实现呢?
答案 0 :(得分:25)
我会按照您想要的顺序存储它。或者在客户端将其拉出后对其进行排序。
如果这些都不可能,您可以使用aggregation framework:
> 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
}
答案 1 :(得分:4)
这可能在这方面没有帮助,但我想我会添加这个。您还可以选择在写入时对其进行排序,这对于非常规化集合而言往往更好,您不必以多种方式进行排序。
我在为用户创建Feed时在我的应用中发现了这种情况。
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()
,默认情况下会按照您的规格进行排序。
答案 2 :(得分:1)
从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
可用。答案 3 :(得分:-3)
执行find()后,您可以对返回值使用sort()。
db.collection.find({},{"answers.name":1}).sort({"answers.name":1})
find将提取集合中所有文档的名称字段。然后排序将按名称对其进行排序,升序。
http://www.mongodb.org/display/DOCS/Sorting+and+Natural+Order