嵌套对象列表项上的$ near运算符

时间:2017-10-09 14:30:29

标签: mongodb

我有一个带有嵌套对象列表(events)的对象集合的mongo db,如下所示:

{
    "_id" : ObjectId("59db84093f2fba2bf0bcfa90"),
    "progressStatus" : "NOT_STARTED",
    "events" : [ 
        {
            "issueDate" : ISODate("2017-10-09T00:00:00.000Z"),
            "eventType" : "xyz",
            "location" : {
                "point" : {
                    "type" : "Point",
                    "coordinates" : [ 
                        25.6011977000001, 
                        45.6579755
                    ]
                }
            },
            "cancelled" : false,
        }
    ]
}

尝试在事件中使用$near$nearSphere运算符进行查询。$。location:

{  
   "events":{  
      "$elemMatch":{  
         "eventType":"xyz",
         "$and":[  
            {  
               "cancelled":false
            },
            {  
               "location.point":{  
                  "$nearSphere":{  
                     "$geometry":{  
                        type:"Point",
                        coordinates:[  
                           25.601198,
                           45.657976
                        ]
                     },
                     "$maxDistance":20.4
                  }
               }
            }
         ]
      }
   }
}

此查询给出了一个错误:

Error: error: {
    "waitedMS" : NumberLong(0),
    "ok" : 0,
    "errmsg" : "geoNear must be top-level expr",
    "code" : 2
}

应该怎么做?

1 个答案:

答案 0 :(得分:2)

海王星,这是因为使用$ nearSphere的地理空间查询使用geoNear命令来获取文档,而geoNear表达式(运行命令时)需要在查询的顶层。在您的示例中,它恰好处于低级别(在elemMatch内),在构造对geoNear的调用时引发错误。

据我了解,您的2dsphere索引位于" events.location.point",对吗?  因此,您可以进行以下查询:

db.sample6.find({"events": {$elemMatch: {$and: [{eventType: "xyz"},{cancelled: false}]}}, "events.location.point": {"$nearSphere": {"$geometry": {type: "Point", coordinates: [25.601198, 45.657976]}, "$maxDistance": 20.4}}})

或只是

db.sample6.find({"events.eventType": "xyz", "events.cancelled": false, "events.location.point": {"$nearSphere": {"$geometry": {type: "Point", coordinates: [25.601198, 45.657976]}, "$maxDistance": 20.4}}})

我认为这最后一个更明智,因为它已经有AND行为,而不需要$和使用。此外,如果可能的话,它将更清晰,更少混淆(因为这些查询有很多括号和括号)来构建地理空间信息就在" location"字段(如果它只包含坐标)。