获取阵列中最近的位置

时间:2017-03-06 15:31:05

标签: javascript mongodb geolocation aggregation-framework

我有一个简单的文档,它在一个数组中有3个位置对象。

数据:

{
    "_id" : ObjectId("57c3c479a306b3613cf1ee5b"),
    "location_history" : [ 
        {
            "location_name" : "Area 1",
            "date" : 1472447609,
            "_id" : ObjectId("57c3c479ac5a69612f0e0899"),
            "location" : [ 
               24.9532107, 67.1790576
            ]
        }, 
        {
            "location_name" : "Area 2",
            "date" : 1472448059,
            "_id" : ObjectId("57c3c63bac5a69612f0e089c"),
            "location" : [ 
               24.9663937, 67.1462044
            ]
        }, 
        {
            "location_name" : "Area 3",
            "date" : 1472448987,
            "_id" : ObjectId("57c3c9dbac5a69612f0e08a0"),
            "location" : [ 
               -24.987325, 115.1862298
            ]
        } 
}

问题:我需要在此数组中获取最接近的位置。

查询我尝试过:

db.getCollection('consumers_locations').aggregate([
    {"$unwind": "$location_history"},
    {"$match":{"_id":ObjectId("57c3c479a306b3613cf1ee5b")}},
    {"$project" : { "abc" : "$location_history.location"} },
    { $geoNear: {
        near: { type: "Point", coordinates: [ 24.942785, 67.157855 ] },
        distanceField: "distance",
        query : {"_id" : "_id"},
        uniqueDocs: true,
        includeLocs: "search_history.location",
        maxDistance : 10000
      }
    }
])

但是我收到了错误:

"ok" : 0,
"errmsg" : "$geoNear is only valid as the first stage in a pipeline.",
"code" : 2,
"codeName" : "BadValue"

预期输出:

{
    "_id" : ObjectId("57c3c479a306b3613cf1ee5b"),
    "location_history" : [ 
        {
            "location_name" : "Area 1",
            "date" : 1472447609,
            "_id" : ObjectId("57c3c479ac5a69612f0e0899"),
            "location" : [ 
               24.9532107, 67.1790576
            ]
        }, 
        {
            "location_name" : "Area 2",
            "date" : 1472448059,
            "_id" : ObjectId("57c3c63bac5a69612f0e089c"),
            "location" : [ 
               24.9663937, 67.1462044
            ]
        }
}

1 个答案:

答案 0 :(得分:0)

您的架构不可行。索引用于对集合中的文档进行排序,而不是对文档中的子文档进行排序。

考虑创建一个单独的location_history集合,其中包含对consumers_locations中父文档的引用。例如。对于您的对象,该集合可能如下所示:

db.getCollection('location_history').insert([
        {
            "consumer_location": ObjectId("57c3c479a306b3613cf1ee5b"),
            "location_name" : "Area 1",
            "date" : 1472447609,
            "_id" : ObjectId("57c3c479ac5a69612f0e0899"),
            "location" : [ 
               24.9532107, 67.1790576
            ]
        }, 
        {
            "consumer_location": ObjectId("57c3c479a306b3613cf1ee5b"),
            "location_name" : "Area 2",
            "date" : 1472448059,
            "_id" : ObjectId("57c3c63bac5a69612f0e089c"),
            "location" : [ 
               24.9663937, 67.1462044
            ]
        }, 
        {
            "consumer_location": ObjectId("57c3c479a306b3613cf1ee5b"),
            "location_name" : "Area 3",
            "date" : 1472448987,
            "_id" : ObjectId("57c3c9dbac5a69612f0e08a0"),
            "location" : [ 
               -24.987325, 115.1862298
            ]
        } 
]);

关于错误,the docs读取:

  

您只能使用$ geoNear作为管道的第一阶段。

因为只有第一阶段可以从索引中受益。