1

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

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

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

数组中的 _idscars与其他集合相关的位置,例如cars.
现在,每个车主都可以拥有多辆汽车,而且每辆汽车都可以拥有多个车主(只是多对多关系)。

例如

[
{'_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
}
4

2 回答 2

0

我会用 2 个查询来做到这一点。它将要求您在调用代码中存储一个临时变量(我将其命名为“汽车”)。它应该看起来像这样:

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

var shared = db.owners.find({'name':{ '$ne': 'Mr. A'}, 'cars': {'$in':cars}}, {'name':1})
于 2013-04-24T10:55:26.313 回答
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}}}
)

我尚未测试上述查询,但我鼓励您尝试一下。

于 2013-04-24T09:40:12.387 回答