エラーは、 $ unwindを実行すると、配列ではなくなったためです。
したがって、 $ size
>
。
あなたは、彼らが何をしているのかを理解せずに、いくつかの既存の答えを「マージ」しようとしているようです。ここで本当に必要なのは、 $ filter
です。
および $ size
db.collection.aggregate([
{ "$project": {
"total": {
"$size": {
"$filter": {
"input": "$Array",
"cond": { "$eq": [ "$$this.field1", "a" ] }
}
}
}
}}
])
または、 $ reduce
を使用して「車輪の再発明」を行います。
:
db.collection.aggregate([
{ "$project": {
"total": {
"$reduce": {
"input": "$Array",
"initialValue": 0,
"in": {
"$sum": [
"$$value",
{ "$cond": [{ "$eq": [ "$$this.field1", "a" ] }, 1, 0] }
}
}
}
}}
])
または、 $ unwind コード>
、実際には $ group
もう一度、一致数を「カウント」するために:
db.collection.aggregate([
{ "$unwind": "$Array" },
{ "$match": { "Array.field1": "a" } },
{ "$group": {
"_id": "$_id",
"total": { "$sum": 1 }
}}
])
最初の2つの形式は、最新のMongoDB環境に「最適」です。 $ unwind
を含む最終フォーム
および $ group
は「レガシー」構造であり、MongoDB 2.6以降、このタイプの操作には実際には必要ありませんが、演算子は少し異なります。
これらの最初の2つでは、基本的に field1
を比較しています。 それがまだ配列である間の各配列要素の値。両方の $ filter
および $ reduce
は、既存のアレイを適切に操作するように設計された最新のオペレーターです。集計を使用して、それぞれで同じ比較が行われます $ eq
指定された引数が「等しい」かどうかに基づいてブール値を返す演算子。この場合、各配列メンバーで "a"
の期待値になります 。
$ filter
の場合
、 "cond"
で指定された条件を満たさなかった要素を除いて、配列は実際にはそのまま残ります。 アレイから削除されます。出力として「配列」がまだあるので、<を使用できます。 code> $ size
そのフィルター条件が処理された後に残っている配列要素の数を測定する演算子。
$ reduce
一方、配列要素を処理し、各要素に対する式と、 "initialValue"
で初期化した格納された「アキュムレータ」値を提供します。 。この場合、同じ $ eq
テストは、 $ cond
内で適用されます。
オペレーター。これは「三元」またはif/ then / else
ブール値を返すテスト済みの式がthen
を返すことを可能にする条件演算子 true
の場合の値 またはelse
false
の場合の値 。
その式では、 1
を返します。 または0
それぞれ、その戻り値と現在の「アキュムレータ」 "$$ value"
を加算した全体的な結果を提供します。 $ sum
これらを足し合わせる演算子。
最終的なフォームでは、 $ unwind
を使用しました
アレイ上。これが実際に行うことは、配列メンバーを分解して、すべての配列メンバーと元のドキュメントの関連する親フィールドの「新しいドキュメント」を作成することです。これにより、すべてのアレイメンバーのメインドキュメントが効果的に「コピー」されます。
$ unwind
ドキュメントの構造が「よりフラットな」形式に変更されます。これが、後続の $matchを実行できる理由です。コード>
一致しないドキュメントを削除するパイプラインステージ。
これにより、 $ group
に移動します。
これは、共通のキーに関連するすべての情報を「まとめる」ために適用されます。この場合、それは _id
です。 元のドキュメントのフィールド。もちろん、 $ unwind
。この「共通キー」を単一のドキュメントとして戻すと、 $ sum
アキュムレータ。
残りの「配列」を元に戻したい場合は、 $ push
残りのメンバーのみでアレイを再構築します:
{ "$group": {
"_id": "$_id",
"Array": { "$push": "$Array" },
"total": { "$sum": 1 }
}}
ただし、もちろん、 $ size
を使用する代わりに
別のパイプラインステージでは、 $ sum