MongoDB $ nin嵌入式文档的某些字段

时间:2014-12-07 20:49:12

标签: mongodb

如果我的架构有这样的嵌入式文档:

location: {
    coordinates: [-41.588221, 71.123812],
    unitNumber: '4a',
    streetAddress: '1 Abc Lane',
    <Other location-related data>
}

我想使用$nin根据位置排除该文档和其他文档,但我只有unitNumbercoordinates,是否有办法正确执行此操作。

例如,假设我想从结果集中排除以下位置数组:

locations = [
    {coordinates: [-41.2342432, 71.812312], unit: '4a'},
    {coordinates: [-40.2242432, 70.212352], unit: '7d'},
    {coordinates: [-42.2546432, 72.312312], unit: '10b'},
    {coordinates: [-41.2342132, 61.812312], unit: '1z'}
]

根据上述架构,有没有办法做到这一点?我不相信使用{location: {$nin: locations}}会有效,因为它会要求locations中的每个对象都有整个嵌入式文档才有资格排除。

2 个答案:

答案 0 :(得分:1)

为了排除符合特定locationunit对的文档。

  • 撰写一个匹配我们所有文档的条件对象 需要排除。
  • 这是使用coordinates字段的$all运算符完成的。
  • 使用逻辑$nor运算符排除匹配的文档。

尽可能避免使用$nin运算符optimize您的查询。

查询组合需要在客户端完成,

var locationsToExclude= [ {coordinates: [-41.2342432, 71.812312], unit: '4a'}, 
                          {coordinates: [-40.2242432, 70.212352], unit: '7d'},
                          {coordinates: [-42.2546432, 72.312312], unit: '10b'},
                          {coordinates: [-41.2342132, 61.812312], unit: '1z'} 
                        ]

var findCondition = {$nor:[]};
locationsToExclude.forEach(function(i){
    var coordinates = i.coordinates;
    var unitNumber = i.unit;
    var condition = {"coordinates":{$all:coordinates},
                     "unitNumber":unitNumber};
    findCondition.$nor.push(condition);
})
db.location.find(findCondition);

答案 1 :(得分:0)

您可以使用aggregate仅使用坐标和单位投影位置,与$nin匹配条件并再次投影以使用$$ ROOT中的数据获取原始文档:

db.location.aggregate([   
     {$group : { _id : "$location", data: { $push: "$$ROOT" }}},
     {$project: { _id: { coordinates: "$_id.coordinates", unit: "$_id.unitNumber" }, data : 1}}, 
     {$match : {_id : {$nin : [
          {coordinates: [-41.2342432, 71.812312], unit: '4a'}, 
          {coordinates: [-40.2242432, 70.212352], unit: '7d'}, 
          {coordinates: [-42.2546432, 72.312312], unit: '10b'}, 
          {coordinates: [-41.2342132, 61.812312], unit: '1z'} ]
     }}},
     {$unwind: "$data"},
     {$project: {_id: 0, location: "$data.location"}}
]);

在上一个$项目中,添加您需要从原始文档(数据)获取的更多字段,例如field1: "$data.field1", field2: "$data.field2"