オブジェクトのネストされた配列をソートする方法を探しています。
次に例を示します。
{
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クエリ言語でサポートされていない動作を実装できます。
たとえば、オブジェクトの配列をフィールドの1つで並べ替えるには、次のようにします。
// {
// "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
のみが利用可能です。