あなたが取る必要があるアプローチは、(与えられた順序で)以下のパイプラインの手順を使用して集約パイプラインを実行している関係:
1)$match
パイプラインに入るフィルタ文書へ。式にequality checks for the value of the same fieldが含まれている場合は、$in
演算子を$or
の代わりに使用することを検討してください。これは、SQLのWHERE
節に似ています。代わり
SELECT name, images, state, slug
WHERE
(name = 'Camden') OR
(name = 'Virginia Beach') OR
(name = 'Annapolis')
2の
SELECT name, images, state, slug
WHERE name in ('Camden', 'Virginia Beach', 'Annapolis')
)$lookup
左外側がstate
コレクションである「参加」コレクションからの文書にフィルタリングする同じデータベースにunshardedコレクションに参加行います処理のために。 $lookup
ステージは、入力ドキュメントのstate
フィールドと "joined"コレクションステートのドキュメントの_id
フィールドとの一致が一致します。
3)$unwind
- あなたはそれとして、配列を平らにすることができるように、あなたのパイプラインに$unwind
段階を追加する必要がありますので、前$lookup
パイプラインの結果から、新しいフィールドが配列であります非正規化フィールドとしてさらに処理する必要があります。
4)$group
すべてのドキュメントをグループ化し、前のパイプラインのフィールドを持つ配列relatedCitiesを作成するパイプラインステップ。 $group
パイプライン演算子は、SQLのGROUP BY
節に似ています。 SQLでは、集約関数を使用しない限り、GROUP BY
は使用できません。同じように、MongoDBでも集約関数を使用する必要があります。集計関数hereの詳細を読むことができます。
配列を作成する必要があるaccumulator演算子は、$push
です。あなたはSQL SELECT
句とどうなるのかに似て -
5)$project
最終段階は、その後、先行するパイプラインの文書からプロパティを選択するか、名前を変更するために使用されます。文字列リテラルで新しいフィールドを作成するには、$literal
演算子が必要です。これは、SQLのAS
またはALIAS
キーワードに似ています。
ここで注目すべきことは、パイプラインを実行するときにMongoDBパイプ演算子が互いにパイプすることです。ここで "Pipe"はLinuxの意味をとります。演算子の出力は、次の演算子の入力になります。各演算子の結果は、新しい文書集合です。 Mongoのは、上記のパイプラインを実行して、次のように:
collection | $match | $lookup | $unwind | $group | $project => result
を今、あなたはモンゴシェルでこの集約パイプラインを実行すると、結果はあなたがcursor
にtoArray()
メソッドを使用するときに取得配列になりますcity
コレクションでaggregate()
メソッドを呼び出すことから戻りました。
あなたは、最初の集計フィールドを持つ新しいcity
文書であるゼロインデックスを通じて結果配列内の唯一の要素にアクセスすることにより、city
コレクション内の新しい都市のエントリを作成し、上のsave()
メソッドを使用することができますドキュメントを永続させるための都市コレクション。
次の例では、上記の概念を示しています
var pipeline = [
{
"$match": {
"name": { "$in": ["Camden", "Virginia Beach", "Annapolis"] }
}
},
{
"$lookup": {
"from": "state",
"localField": "state",
"foreignField": "_id",
"as": "states"
}
},
{ "$unwind": "$states" },
{
"$group": {
"_id": null,
"relatedCities": {
"$push": {
"images": "$images",
"slug": "$slug",
"name": "$name",
"stateSlug": "$states.slug"
}
}
}
},
{
"$project": {
"_id": 0,
"name": { "$literal": "Lewes" },
"relatedCities": 1
}
}
],
newCity = db.city.aggregate(pipeline).toArray()[0];
db.city.save(newCity);