文書の埋め込み配列から一致するエントリだけを返し、これを実践的に見つけることができない集約パイプラインを作成する方法をいくつか試しました。MongoDbの集計結果でelemMatchを満たすサブ文書のみを返す
私の非常に不器用でエラーを起こしやすいアプローチを避けるMongoDBの機能はありますか?
「ワークショップ」コレクション内の文書は、次のようになります...
{
"_id": ObjectId("57064a294a54b66c1f961aca"),
"type": "normal",
"version": "v1.4.5",
"invitations": [],
"groups": [
{
"_id": ObjectId("57064a294a54b66c1f961acb"),
"role": "facilitator"
},
{
"_id": ObjectId("57064a294a54b66c1f961acc"),
"role": "contributor"
},
{
"_id": ObjectId("57064a294a54b66c1f961acd"),
"role": "broadcaster"
},
{
"_id": ObjectId("57064a294a54b66c1f961acf"),
"role": "facilitator"
}
]
}
ときにグループメンバーがワークショップに与えられた役割を割り当てられるようにグループの配列の各エントリが一意のIDを提供しますその塩漬けされたIDを持つURLをヒットします。
ObjectId("57064a294a54b66c1f961acb")
のようなグループ配列のエントリに一致する_idがある場合、私は集約パイプラインからこのような単一のレコードを返す必要があります - 基本的に埋め込みグループ配列から一致するエントリを返します。この例では
{
"_id": ObjectId("57064a294a54b66c1f961acb"),
"role": "facilitator",
"workshopId": ObjectId("57064a294a54b66c1f961aca")
},
、workshopIdは、親文書を識別するために余分なフィールドとして追加されているが、残りの部分は、整合_idを有する元のグループエントリからALLフィールドであるべきです。
私が採用しているアプローチはこれを達成することはできますが、問題は多く、おそらく効率的ではありません(フィルタ句を繰り返します)。
return workshopCollection.aggregate([
{$match:{groups:{$elemMatch:{_id:groupId}}}},
{$unwind:"$groups"},
{$match:{"groups._id":groupId}},
{$project:{
_id:"$groups._id",
role:"$groups.role",
workshopId:"$_id",
}},
]).toArray();
さらに悪いことに、それが明示的にエントリから名前のフィールドが含まれているので、それがレコードに追加されている任意の将来のフィールドを省略します。私はまた、配列エントリのフィールドが何であるか分からない限り、このルックアップ操作を '招待状'や他の組み込み名前付き配列の場合に一般化することはできません。
私は、パイプラインの$プロジェクト段階で$または$ elemMatch演算子を使用するのが正しいアプローチであるのか疑問に思っていますが、これまで無視されていたか、パイプライン実行時にオペレータの有効性エラーが発生しました。ドキュメントの配列からだけ一致するエントリを返すために -
QUESTION
はこのかなり主流の問題で私を助ける別の集計演算子または別のアプローチはありますか?
いいえ、あなたの質問と用法は、配列要素の* "複数の条件に一致する複数の条件" *がある場合にのみ '$ elemMatch'を必要とするため、ややこしいことです。それ以外の場合(2番目の '$ match'文のように" dot notation "を使用します) –
あなたの集計クエリは私にはうまく見えます。また、フィールドを知らなくても、すべてのタイプの埋め込みオブジェクト配列で機能する汎用の集計クエリを作成することはできません。それはそれをより複雑にし、エラーを起こしやすくします。 –
結論として、配列メンバをトップレベルのドキュメントのように見せたいのであれば、 '$ unwind'を使い、最後に' $ project'を使う必要があります。また、カーソルの結果で受け取った基本文書を処理して出力し、送信先に出力を変換するだけで、受け入れて生きることができます。返される各ドキュメントの各配列メンバーを反復する単純なケース。 –