2016-11-14 4 views
2

のフィールドと配列の要素のフィールドを比較すると、私はこのようなコレクションのグループがあります。MongoDBの

{ 
    "_id" : ObjectId("5822dd5cb6a69ca404e0d93c"), 
    "name" : "GROUP 1", 
    "member": [ 
     { 
      "_id": ObjectId("5822dd5cb6a69ca404e0d93d") 
      "user": ObjectId("573ac820eb3ed3ea156905f6"), 
      "task": ObjectId("5822ddecb6a69ca404e0d942"), 
     }, 
     { 
      "_id": ObjectId("5822dd5cb6a69ca404e0d93f") 
      "user": ObjectId("57762fce5ece6a5d04457bf9"), 
      "task": ObjectId("5822ddecb6a69ca404e0d943"), 
     } 
    ], 
    curTask: { 
     "_id": ObjectId("5822ddecb6a69ca404e0d942"), 
     "time": ISODate("2016-01-01T01:01:01.000Z") 
    } 
} 
{ 
    "_id" : ObjectId("573d5ff8d1b7b3b32e165599"), 
    "name" : "GROUP 2", 
    "member": [ 
     { 
      "_id": ObjectId("574802e031e70b503eabe195") 
      "user": ObjectId("573ac820eb3ed3ea156905f6"), 
      "task": ObjectId("5775f1a74b41037e246a51d1"), 
     }, 
     { 
      "_id": ObjectId("574802e031e70b503eabe198") 
      "user": ObjectId("573ac79beb3ed3ea156905f4"), 
      "task": ObjectId("576cfa042c0a4054794dd242"), 
     } 
    ], 
    curTask: { 
     "_id": ObjectId("577249a2f9dba0c750ef705b"), 
     "time": ISODate("2016-01-01T01:01:01.000Z") 
    } 
} 
{ 
    "_id" : ObjectId("574802e031e70b503eabe194"), 
    "name" : "GROUP 3", 
    "member": [ 
     { 
      "_id": ObjectId("574be0a2bf16234f5a752f83") 
      "user": ObjectId("573ac79beb3ed3ea156905f4"), 
      "task": ObjectId("5822ddecb6a69ca404e0d942"), 
     }, 
     { 
      "_id": ObjectId("574d397d6e9f07d64d1e4e40") 
      "user": ObjectId("57762fce5ece6a5d04457bf9"), 
      "task": ObjectId("5822ddecb6a69ca404e0d943"), 
     } 
    ], 
    curTask: { 
     "_id": ObjectId("5822ddecb6a69ca404e0d942"), 
     "time": ISODate("2016-01-01T01:01:01.000Z") 
    } 
} 

と私はすべてのグループを見つけることができるようにしたい場所をグループ1のOBJECTID 573ac820eb3ed3ea156905f6(第一のユーザーを持つユーザー)は、currentTaskと同じタスクを実行しません。これまでのところ私はこのクエリを書いてきました:

db.getCollection('groups').find({"member":{ "$elemMatch": {"user": ObjectId("573ac820eb3ed3ea156905f6") 
, "task": { "$ne":"this.curTask._id"}}}}) 

をしかし、これは、それはまだユーザー573ac820eb3ed3ea156905f6が彼task === curTask._idを有する基を返すように動作していないようでした。 elemMatchの前半は正常に動作しているようです(グループ内のobjectidが573ac820eb3ed3ea156905f6のメンバーのみが検索されますが、グループ3はそのユーザーを持っていないので、グループ1と2は返されます)。しかし、mongodbとフィールド配列のオブジェクト内のドキュメントの別のフィールドに置き換えます。誰でも私はどのようにこの比較を行うことができますか考えている?

まず - - $whereを使用して

+0

ポストダンプデータが –

+0

あなたが第一条件に一致したアレイ内の他のメンバーのタスクを気にしてください私たちは、この内部要素マッチャ –

+0

を使用する方法についての手掛かりを得ていません。 – hyades

答えて

1

は問題には、次の2つの解決策があります。 $whereを使用すると、mongodbクエリ内でJavascriptコードを使用できます。コードを柔軟にしますが、より最適化されたmongoDB C++コードではなく、JavaScriptコードを実行する必要があるため、実行速度が遅いという欠点があります。

db.getCollection('groups').find({ 
    $where: function() { 
      var flag = 0; 

      for(var i=0; i<obj.member.length;i++) { 
        if(obj.member[i].user.str == ObjectId("573ac820eb3ed3ea156905f6").str && obj.member[i].task.str != obj.curTask._id.str){flag = 1; break;} 
       } 
      return flag; 
     } 
    }) 

第2 - 集約パイプラインを使用する。ここでは、配列の巻き戻し、記述されたマッチの実行、最後に必要に応じて配列の再作成を行います。 member配列内の一致しない要素が必要ない場合は、最後のグループ化部分を省略できます。

[ 
{$match: {'member.user': ObjectId("573ac820eb3ed3ea156905f6")}}, 
{$unwind: '$member'}, 
{$project: { 
    name: 1, 
    member: 1, 
    curTask: 1, 
    ne: {$and: [{$ne: ['$member.task', '$curTask._id']}, {$eq: ['$member.user', ObjectId("573ac820eb3ed3ea156905f6")]}]} 
    }}, 
{$group: { 
    _id: '$_id', 
    member: {$push: '$member'}, 
    curTask: {$first: '$curTask'}, 
    name: {$first: '$name'}, 
    check: {$sum: {$cond: ['$ne', 1, 0]}} 
    }}, 
{$match: {check: {$gt: 0}}} 
] 
+0

ありがとうございました。私はあなたがクエリでjsコードを使用できることを知りませんでした。第1の方法は完全に私のために働いています( '.str'を' + '' 'に変更するだけで、ユーザがまだタスクを割り当てていない場合もカバーするので、タスクは' null'です)。 – Megazero