1

私はmembersプロパティに含まれているgroupオブジェクトを持っています。 membersプロパティはオブジェクトの配列です。そのオブジェクトは次のプロパティを持っています。mongooseでスキーマプロパティでフィルタリングする方法

{"id" : "1", "status" : 1} 

私の要件は、(指定したidによって)与えられたgroupオブジェクトの状態1を、持っているユーザーの一覧を取得することです。

これは可能なことですが、ID照会の簡単な取得とforeachです。しかし、これを行うための事前照会はありますか?

私の全体的なGroupオブジェクトは次のとおりです。

var UserSchema = new Schema({ 
    user_id:{ 
    type : Schema.ObjectId, 
    ref : 'User', 
    default : null 
    }, 
    status:{ 
    type : Number, 
    default : null /* 1 - pending | 2 - rejected | 3 - accepted*/ 
    }, 
}); 

var GroupSchema = new Schema({ 
    type:{ 
    type : Number, 
    default : 1 /* 1 - group | 2 - community*/ 
    }, 
    name:{ 
    type:String, 
    default:null 
    }, 
    members:[UserSchema] 

},{collection:"groups"}); 

ありがとうございます。

db.groups.find({"members.status":1}, {"members":1}); 

これは、あなたが(とユーザIDを想定して、特定のuser_idに基づいて照会する場合は、ステータス1を持っているすべてのユーザーを取得します:

+0

を使用して、与えられた_グループ_オブジェクトの代わりに、_post_オブジェクトに対してもしかして? – chridam

+0

スキーマの定義を与えるのではなく、達成しようとしていることを理解しやすいようにサンプル文書と予想される出力を共有するのがよいでしょう。 – superUser

+0

@chridam 'group'オブジェクトです。質問を編集しました。 –

答えて

2

あなたは、与えられたグループ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); 
    }); 
}); 
+0

検索はどのように動作しますか –

+0

@sacDahal同じデータベース内のシャードされていないコレクションに「左外部結合」を実行して、「結合」されたコレクションの文書をフィルタリングして処理します。 '$ lookup'ステージは、入力ドキュメントのフィールドと、" joined "コレクションのドキュメントのフィールドとの一致を行います。ときどき '$ lookup'はMongoDBをリレーショナルデータベースのように扱うために誤用されることがありますが、開発者はその使用がいつ適切であるか、いつアンチパターンであるかを知るべきです。 – chridam

+0

私のmongoDBのバージョンは '$ filter'パイプラインステージと互換性がありません。 '$ filter'を置き換えるために使用できる他の段階がありますか? –

0

と仮定すると、あなたのコレクション名は、あなたがこのように照会することができ、groupsですここでは「1A」)は、このようなオブジェクトに追加することができます。

db.groups.find({"members.status":1, "members.user_id":"1A"}, {"members":1}); 
関連する問題