2016-11-14 101 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") 
    } 
} 

而且我希望能夠找到所有羣裏有OBJECTID 573ac820eb3ed3ea156905f6(第1組第一個用戶的用戶)不要執行與currentTask相同的任務。到目前爲止,我已經寫了這個查詢:

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

但這似乎並沒有工作,因爲它仍然會返回其中用戶573ac820eb3ed3ea156905f6有他task === curTask._id組。 elemMatch的上半部分似乎工作正常(只發現用戶與objectid 573ac820eb3ed3ea156905f6成員中的用戶,查詢只返回組1和2,因爲組3沒有該用戶。)但我似乎無法讓mongodb比較一個字段在數組的對象中與文檔的另一個字段。任何人都有任何想法如何做這個比較?

+0

後轉儲數據 –

+0

沒有得到一個線索關於我們如何能夠利用這裏面的單元匹配 –

+0

你關心的陣列中的其他成員已經匹配了第一個條件的任務。 – hyades

回答

1

有兩個解決問題的方案 -

首先 - 使用$where。通過使用$where,您可以在mongodb查詢中使用Javascript代碼。使代碼更靈活,但缺點是運行速度慢,因爲必須運行Javascript代碼而不是更優化的mongoDB C++代碼。

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; 
     } 
    }) 

第二 - 使用聚合管道。在這裏我展開數組,按照描述進行匹配,最後根據需要重新創建數組。如果不需要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代碼。第一種方式完全適合我(我只需要將'.str'改爲'+''',這樣它也將覆蓋用戶沒有任何任務分配給他的情況,所以他的任務是'空')。 – Megazero