2014-12-07 70 views
2

如果我在我的架构中有像这样的嵌入文档:

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中的每个对象都要使整个嵌入式文档符合排除条件。

回答

1

为了排除与某些locationunit对匹配的文档。

  • 撰写一个条件对象,它匹配我们需要排除的所有文档。
  • 这是使用$all运算符为coordinates字段完成的。
  • 使用逻辑$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); 
+0

这工作完美,谢谢!也担心'$ nin'的表现,所以我很高兴这是解决方案:) – jtmarmon 2014-12-08 21:57:14

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"