集約フレームワークはそのようなものに理想的です。次のパイプラインを実行して、目的の結果を取得することを検討してください。
pipeline = [
{
"$match": {
"name": "james",
"books.year": 1990
}
},
{
"$project": {
"numberOfBooks": {
"$size": {
"$filter": {
"input": "$books",
"as": "el",
"cond": { "$eq": [ "$$el.year", 1990 ] }
}
}
}
}
}
];
db.collection.pipeline(pipeline);
上記のパイプラインは、新しい $ filter コード>
MongoDB 3.2で使用可能な演算子は、指定された条件を満たす配列を生成します。つまり、基準を満たさない外部要素をフィルター処理します。最初の $ match コード>
$ size
>
引数として単一の式を受け入れる演算子を使用すると、結果の配列の要素数が得られるため、目的の書籍数が得られます。
$を使用しない代替ソリューションの場合フィルタ
以前のバージョンでは演算子が見つからなかった場合は、次のパイプライン操作を検討してください。
pipeline = [
{
"$match": {
"name": "james",
"books.year": 1990
}
},
{
"$project": {
"numberOfBooks": {
"$size": {
"$setDifference": [
{
"$map": {
"input": "$books",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el.year", 1990 ] },
"$$el",
false
]
}
}
},
[false]
]
}
}
}
}
];
db.collection.pipeline(pipeline);
$ project
>
パイプラインステージでは、書籍の配列を調整して、1990年のないドキュメントを削除します。これは、 $ setDifference
および $ map
$ map
本質的に、演算子は、配列の各要素の部分式で評価されたロジックの結果として値を保持する新しい配列フィールドを作成します。 $ setDifference
次に、演算子は、最初のセットには表示されるが2番目のセットには表示されない要素を含むセットを返します。つまり、最初のセットに対して2番目のセットの相対的な補数を実行します。この場合、1990年の要素を含む最終的な本の配列が返され、その後 $ size
結果の配列の要素数を計算して、本の数を計算します。
を使用するソリューションの場合$ unwind
オペレーター、次のことを念頭に置いてください(コメントの@BlakesSevenからのこの洞察に満ちた応答に感謝します):
最後の手段として、次のパイプラインを実行します。
pipeline = [
{
"$match": {
"name": "james",
"books.year": 1990
}
},
{ "$unwind": "$books" },
{
"$match": { "books.year": 1990 }
},
{
"$group": {
"_id": null
"count": { "$sum": 1 }
}
}
]
db.collection.pipeline(pipeline)