あなたは、与えられたグループIDとメンバーアレイステータスフィールドでグループコレクションで文書をフィルタリングする集約フレームワークを使用することができます。これは最初のパイプライン段階で、$match
オペレータ駆動です。
次のパイプラインステップは、与えられた条件に基づいてメンバ配列のサブセットを選択する$filter
演算子である必要があります。これは、前のパイプラインが配列/フィールドレベルではなく、ドキュメントレベルでのみフィルタリングするために必要です。
フィルタリングされた配列を取得したら、メンバリストに "populate"する手段として$lookup
関数を適用できます。 localField
が配列であり、あなたは、単一の要素であるforeignField
に対して、その内部の要素を一致させたいので、あなたは$lookup
演算子を適用する前に$unwind
アグリゲーションパイプラインの1つの段階として配列する必要があります。
次の例では、あなたがあなたのケース内のすべての上記の手順を適用する方法を示しています
Group.aggregate([
{
"$match": {
"_id": groupId,
"members.status": 1
}
},
{
"$filter": {
"input": "$members",
"as": "member",
"cond": { "$eq": ["$$member.status", 1] }
}
}
{ "$unwind": "$members" },
{
"$lookup": {
"from": "users"
"localField": "members.user_id",
"foreignField": "_id",
"as": "member"
}
}
]).exec(function(err, results) {
if (err) throw err;
console.log(results);
});
結果は、グループやユーザー属性の両方を持っている文書のリストが含まれます。
あなたのMongoDBバージョンは、バージョン3.2で導入され$filter
と$lookup
演算子をサポートしていない場合。X以降、次いで$project
パイプライン内の配列エレメントをフィルタリングする$setDifference
と$map
オペレータコンボの使用を検討してください。
$map
演算子は、本質的に、評価された論理の結果として値を保持する新しい配列フィールドを、配列の各要素の部分式に保持します。 $setDifference
演算子は、最初のセットに表示され、2番目のセットには表示されないエレメントを含むセットを返します。すなわち、第1のセットに対して相対的な第2のセットの補数を実行する。この場合、親ドキュメントに関連しない要素を持つ最終メンバ配列がstatus
プロパティを介して返されます。
は$project
パイプラインの工程の後に、集約演算を実行し、返されたドキュメントは、プレーンJavaScriptのオブジェクトではなく、Mongoose Documents(文書の任意の形状を返すことができる)であるため、あなたが使用できるようにMongoose Documentsに結果をキャストする必要があります結果をフィールドに入力します。
次の例では、上記の回避策を示しています。
Group.aggregate([
{
"$match": {
"_id": groupId,
"members.status": 1
}
},
{
"$project": {
"type": 1, "name": 1,
"members": {
"$setDifference": [
{
"$map": {
"input": "$members",
"as": "member",
"in": {
"$cond": [
{ "$eq": [ "$$member.status", 1 ] },
"$$member",
false
]
}
}
},
[false]
]
}
}
}
]).exec(function(err, result) {
if (err) throw err;
var docs = result.map(function(doc) { return new Group(doc) });
Group.populate(docs, { "path": "members" }, function(err, results) {
if (err) throw err;
console.log(JSON.stringify(results, undefined, 4));
res.json(results);
});
});
を使用して、与えられた_グループ_オブジェクトの代わりに、_post_オブジェクトに対してもしかして? – chridam
スキーマの定義を与えるのではなく、達成しようとしていることを理解しやすいようにサンプル文書と予想される出力を共有するのがよいでしょう。 – superUser
@chridam 'group'オブジェクトです。質問を編集しました。 –