これは良い考えだとは思いませんが、ほとんどの場合、ここに「集約」がまったく表示されないため、「グループ化」して配列に追加した後、同様に$push
"status"
によってすべてのコンテンツを配列に キーをグループ化してから、$replaceRoot
でドキュメントのキーに変換します $arrayToObject
を使用 :
db.collection.aggregate([
{ "$group": {
"_id": "$status",
"data": { "$push": "$$ROOT" }
}},
{ "$group": {
"_id": null,
"data": {
"$push": {
"k": "$_id",
"v": "$data"
}
}
}},
{ "$replaceRoot": {
"newRoot": { "$arrayToObject": "$data" }
}}
])
返品:
{
"inProgress" : [
{
"_id" : ObjectId("5b18d31a27a37696ec8b5776"),
"status" : "inProgress",
"description" : "inProgress..."
}
],
"completed" : [
{
"_id" : ObjectId("5b18d31a27a37696ec8b5773"),
"status" : "completed",
"description" : "completed..."
}
],
"pending" : [
{
"_id" : ObjectId("5b18d14cbc83fd271b6a157c"),
"status" : "pending",
"description" : "You have to complete the challenge..."
},
{
"_id" : ObjectId("5b18d31a27a37696ec8b5775"),
"status" : "pending",
"description" : "pending..."
}
]
}
それは大丈夫かもしれませんIF 実際には事前に「集約」しますが、実際のサイズのコレクションでは、コレクション全体を1つのドキュメントに強制するだけで、BSONの制限である16 MBを超える可能性があるため、「」なしでこれを試みることはお勧めしません。このステップの前に何か他のものをグループ化する。
率直に言って、次の同じコードは同じことを行い、集計のトリックやBSON制限の問題はありません:
var obj = {};
// Using forEach as a premise for representing "any" cursor iteration form
db.collection.find().forEach(d => {
if (!obj.hasOwnProperty(d.status))
obj[d.status] = [];
obj[d.status].push(d);
})
printjson(obj);
または少し短い:
var obj = {};
// Using forEach as a premise for representing "any" cursor iteration form
db.collection.find().forEach(d =>
obj[d.status] = [
...(obj.hasOwnProperty(d.status)) ? obj[d.status] : [],
d
]
)
printjson(obj);
集計は「データ削減」に使用され、サーバーから返されるデータを実際に削減せずに単に「結果を再形成」するものは、通常、クライアントコードでより適切に処理されます。何をしてもすべてのデータを返すことになり、カーソルのクライアント処理のオーバーヘッドは大幅に少なくなります。制限はありません。