2013-04-24 18 views
1

我在蒙戈是新的,我真的不知道該怎麼咬這一點:與同一陣列區段Count文件

比方說,我們有這個架構中owners集合:

{ 
    _id: ObjectId, 
    name: "name", 
    cars: [ObjectId, ObjectId, ObjectId, ...] 
} 

凡_ids在cars數組涉及其他收集,說cars
現在,每個車主都可以有很多車,每輛車可以有多個車主(只是多對多的關係)。

E.g.

[ 
{'_id':'1', 'name':'Mr. A', cars: ['1','2',3',4',5'] }, 
{'_id':'2', 'name':'Mr. B', cars: ['6'] }, 
{'_id':'3', 'name':'Mr. C', cars: ['1','2'] }, 
{'_id':'4', 'name':'Mr. D', cars: ['2',3',5','6','7'] }, 
{'_id':'5', 'name':'Mr. E', cars: ['6'] } 
] 

問題是如何檢查哪個車主與先生A共用汽車。
如何獲得導致這樣對於A先生:

[ 
{'owner_id': '3', 'cars': 2}, 
{'owner_id': '4', 'cars': 3} 
] 

我試圖用聚合框架,但我看不到這樣做的方式。


編輯
我寫了這個功能,但我不知道,如果這是正確的方式

function (owner) 
{ 
    ret = {} 
    owner.cars.forEach(function (car) { 
     db.owners.find({cars: car}).forEach(function(own2){ 
      if(own2._id == owner._id){ 
       return; 
      } 
      if(ret[own2._id.str] !== undefined){ 
       ret[own2._id.str] += 1; 
      } 
      else{ 
       ret[own2._id.str] = 1; 
      } 
     }); 
    }); 
    return ret 
} 
+2

你不能在一個查詢/一個聚合中做到這一點。你可以用一個map/reduce工作來完成,但是兩個查詢會更快。 – 2013-04-24 13:23:37

回答

0

如果你只關心與A先生分享的業主,你可以嘗試以下方法:

首先,獲得由A先生擁有的汽車:

var cars = db.owners.findOne({'name':'Mr. A'}) 

然後在業主與A先生類似汽車執行聚集排除A.先生

db.owners.aggregate(
    {'$match':{$and : [{'cars':{'$in':cars}},{'name':{'$ne':'Mr. A'}}]}}, 
    {'$unwind':'$cars'}, 
    {'$group':{'_id':'$_id','owner_id':'$_id','cars':{$sum:1}}} 
) 

我沒有測試過上述查詢,但我鼓勵你去嘗試它。

0

我會用2個查詢來做到這一點。它會要求你在你的調用代碼中存儲一個臨時變量(我已經命名爲'cars')。它應該看起來像這樣:

var cars = db.owners.findOne({'name':'Mr. A'}, {cars:1}) 

var shared = db.owners.find({'name':{ '$ne': 'Mr. A'}, 'cars': {'$in':cars}}, {'name':1})