计算具有相同数组字段的文档

时间:2013-04-24 06:50:42

标签: mongodb many-to-many

我是mongo的新手,我真的不知道如何咬这个:

假设我们在owners集合中有这个模式:

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

cars数组中的_ids与其他集合相关,例如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 个答案:

答案 0 :(得分: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}}}
)

我没有测试过上述查询,但我鼓励您尝试一下。

答案 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})