mongodb 对嵌套的对象数组进行排序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12432727/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sort nested array of objects
提问by Kaylit
I'm looking for a way to sort a nested array of objects.
我正在寻找一种对嵌套对象数组进行排序的方法。
Here's an example:
下面是一个例子:
{
answers : [
{ name : 'paul', state : 'RU' },
{ name : 'steve', state : 'US' },
{ name : 'mike', state : 'DE' },
...
]
}
Suppose now I want to find all the name
, of the answers
array, but how can I sort them in ascending order?
假设现在我要找到所有name
的中,answers
数组,但我怎么能排序他们升序排列?
回答by Eve Freeman
I would store it in the order you want it back out. Or sort it after you pull it out, on the client side.
我会按照你想要的顺序存储它。或者在您将其拉出后对其进行排序,在客户端。
If neither of those are possible, you can use the 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"}}}
]);
produces:
产生:
{
"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
}
回答by corvid
This might not be helpful in this context, but I thought I'd add this. You also have the option to sort it on the write which tends to be better for denormalized collections where you don't have to sort in more than one way.
这在这种情况下可能没有帮助,但我想我会添加这个。您还可以选择在写入时对其进行排序,这对于您不必以多种方式排序的非规范化集合来说往往更好。
I found this situation in my app when creating a feed on a user.
在为用户创建提要时,我在我的应用程序中发现了这种情况。
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 }
}
}
});
}
});
I found it to be pretty handy because you can then use find()
and it will be sorted by your specifications by default.
我发现它非常方便,因为您可以使用find()
它,并且默认情况下它将按照您的规格进行排序。
回答by Xavier Guihot
Starting in Mongo 4.4
, the $function
aggregation operator allows applying a custom javascript function to implement behaviour not supported by the MongoDB Query Language.
从 开始Mongo 4.4
,$function
聚合运算符允许应用自定义 javascript 函数来实现 MongoDB 查询语言不支持的行为。
For instance, in order to sort an array of objects by one of their fields:
例如,为了按对象的一个字段对对象数组进行排序:
// {
// "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" }
// ]
// }
This modifies the array in place, without having to apply a combination of expensive $unwind
, $sort
and $group
stages.
这会就地修改数组,而不必应用昂贵的$unwind
,$sort
和$group
阶段的组合。
$function
takes 3 parameters:
$function
需要3个参数:
body
, which is the function to apply, whose parameter is the array to modify.args
, which contains the fields from the record that thebody
function takes as parameter. In our case"$answers"
.lang
, which is the language in which thebody
function is written. Onlyjs
is currently available.
body
,这是要应用的函数,其参数是要修改的数组。args
,其中包含该body
函数作为参数的记录字段。在我们的情况下"$answers"
。lang
,这body
是编写函数的语言。仅js
当前可用。
回答by Philipp
After performing a find() you can use sort() on the return value.
执行 find() 后,您可以对返回值使用 sort()。
db.collection.find({},{"answers.name":1}).sort({"answers.name":1})
The find would extract the name fields of all documents in the collection. The sort would then sort them by name, ascending.
find 将提取集合中所有文档的名称字段。然后排序将按名称升序对它们进行排序。
http://www.mongodb.org/display/DOCS/Sorting+and+Natural+Order
http://www.mongodb.org/display/DOCS/Sorting+and+Natural+Order