最初のクエリは、間違ったパイプライン演算子を使用していた正しいトラックバックでした。
Artist.native(function(err,collection) {
collection.aggregate(
[
{ "$project": {
"_id": 1,
"name": 1,
"total": { "$size": "$dubs" }
}}
],
function(err,result) {
if (err) return res.serverError(err);
console.log(result);
}
})
もちろん、 $ size
そこでの演算子では、MongoDB 2.6以降のバージョンが必要です。これはおそらく今までに行う必要がありますが、配列の長さを測定するための演算子がなくても同じことができます。
Artist.native(function(err,collection) {
collection.aggregate(
[
{ "$project": {
"_id": 1,
"name": 1,
"dubs": {
"$cond": [
{ "$eq": [ "$dubs", [] ] },
[0],
"$dubs"
]
}
}},
{ "$unwind": "$dubs" },
{ "$group": {
"_id": "$_id",
"name": { "$first": "$name" },
"total": {
"$sum": {
"$cond": [
{ "$eq": [ "$dubs", 0 ] },
0,
1
]
}
}
}}
],
function(err,result) {
if (err) return res.serverError(err);
console.log(result);
}
})
これは、配列のメンバーをカウントすることでも同じことを行いますが、代わりに $ unwind
それらを数えるための配列要素。したがって、それでも実行できますが、それほど効率的ではありません。
さらに、配列が本当に空白であるが、 $ unwind
空の配列を処理します[]
。コンテンツがない場合、そのような要素を含むドキュメントは結果から削除されます。同様に、 $を使用する必要があります。 ifNull
ドキュメントに $ unwind
エラーが発生しないようにします。
実際、この種のクエリを定期的に実行する場合は、最初に計算するのではなく、ドキュメント内の「合計」フィールドを維持する必要があります。 $ inc
を使用します
演算子と $ push コード>
および $ pull
現在のアレイの長さの集計を維持します。
これは、一般的なWaterlineの哲学から少し離れていますが、ネイティブの集計操作をすでに導入しているので、他の領域でもネイティブ操作を使用することでパフォーマンスが向上していることに気付くのはそれほど難しいことではありません。
したがって、次のようなドキュメントでは:
{
"dubs": [{},{},{}],
"name": "The Doors",
"createdAt": "2014-12-15T15:24:26.216Z",
"updatedAt": "2014-12-15T15:24:26.216Z",
"id": "548efd2a436c850000353f4f"
},
{
"dubs": [],
"name": "The Beatles",
"createdAt": "2014-12-15T20:30:33.922Z",
"updatedAt": "2014-12-15T20:30:33.922Z",
"id": "548f44e90630d50000e2d61d"
}
いずれの場合も、希望どおりの結果が得られます。
{
"_id" : ObjectId("5494b79d7e22da84d53c8760"),
"name" : "The Doors",
"total" : 3
},
{
"_id" : ObjectId("5494b79d7e22da84d53c8761"),
"name" : "The Beatles",
"total" : 0
}