有一对夫妇在这里的问题,主要是涉及到你是如何存储的文件。 MongoDB的支持存储在三种格式之一的坐标点:
旧坐标对作为阵列当数据在经度列出然后纬度顺序
[ 74.3236112, 31.5200788 ]
旧坐标对作为对象其中数据可以由名为键来组织,但这些必须订购并明确命名为“LON”和“LAT”分别 “以”:
{ "lon": 74.3236112, "lat": 31.5200788 }
作为GeoJSON格式其中存储的数据可以是任何有效GeoJSON的对象的格式。对于“点”类型是这样的:
{
"type": "Point",
"coordinates": [ 74.3236112, 31.5200788 ]
}
为了证明我有一个集合,在四种不同的格式示例文档。我们要创建的是集合的索引与.createIndex({ "loc": "2dsphere" })
,然后使用聚合管道$geoNear
查询,并从查询点返回的实际距离:
db.geotest.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ 74.3236112, 31.5200788 ]
},
"spherical": true,
"distanceField": "distance"
}}
])
显示从查询中四种不同的格式和计算的距离。请注意,只有两个“有效”格式从查询地点返回0
正确的距离:
{
"_id" : ObjectId("5945f800b4051c7e52c90d1c"),
"email" : "[email protected]",
"firstName" : "abc",
"lastName" : "abc",
"loc" : {
"type" : "Point",
"coordinates" : [
74.3236112,
31.5200788
]
},
"gender" : "Male",
"deviceId" : "YWg8crAjZLCrV",
"createdDate" : ISODate("2017-06-11T11:35:41.601Z"),
"updatedDate" : ISODate("2017-06-17T17:33:10.743Z"),
"distance" : 0
}
{
"_id" : ObjectId("5945f8f6b4051c7e52c90d1e"),
"email" : "[email protected]",
"firstName" : "abc",
"lastName" : "abc",
"loc" : {
"lon" : 74.3236112,
"lat" : 31.5200788
},
"gender" : "Male",
"deviceId" : "YWg8crAjZLCrV",
"createdDate" : ISODate("2017-06-11T11:35:41.601Z"),
"updatedDate" : ISODate("2017-06-17T17:33:10.743Z"),
"distance" : 0
}
{
"_id" : "146138792054898475572",
"email" : "[email protected]",
"firstName" : "abc",
"lastName" : "abc",
"loc" : {
"lat" : 31.5200788,
"lng" : 74.3236112
},
"gender" : "Male",
"deviceId" : "YWg8crAjZLCrV",
"createdDate" : ISODate("2017-06-11T11:35:41.601Z"),
"updatedDate" : ISODate("2017-06-17T17:33:10.743Z"),
"distance" : 5315650.25629941
}
{
"_id" : ObjectId("5945f8b7b4051c7e52c90d1d"),
"email" : "[email protected]",
"firstName" : "abc",
"lastName" : "abc",
"loc" : {
"lat" : 31.5200788,
"lon" : 74.3236112
},
"gender" : "Male",
"deviceId" : "YWg8crAjZLCrV",
"createdDate" : ISODate("2017-06-11T11:35:41.601Z"),
"updatedDate" : ISODate("2017-06-17T17:33:10.743Z"),
"distance" : 5315650.25629941
}
因此为了正确查询,你需要一个“有效”为索引格式。我个人建议使用GeoJSON格式,因为它被广泛用作标准,并且还可以选择存储任何有效的GeoJSON对象,而不仅仅是“点坐标”。
您可以操作的数据转换如下所示:
var ops = [];
db.User.find({
"loc.lng": { "$exists": true },
"loc.lat": { "$exists": true }
}).forEach(function(doc) {
ops.push({
"updateOne": {
"filter": { "_id": doc._id },
"update": {
"$set": {
"loc": {
"type": "Point",
"coordinates": [ doc.loc.lng, doc.loc.lat ]
}
}
}
}
});
if (ops.length >= 1000) {
db.User.bulkWrite(ops);
ops = [];
}
});
if (ops.length > 0) {
db.User.bulkWrite(ops);
ops = [];
}
这将"loc"
数据重新写入修正后的格式,以便在索引和查询会工作。
实际上,在更新之前,您应该在集合上确实执行.dropIndexes()
以节省写入成本,然后在完成后重新创建索引。这不是一个必要的步骤,但它会被推荐。
N.B还具有校正实际上将仍然排除的结果,因为所证明从查询点(这是相同的坐标)的实际距离数据的$minDistace
参数这里是0
。所以在测试中删除这个约束,或者更好地用$geoNear
进行测试。
另请注意有提及的DocumentDB,它不支持聚合流水线协议。这里的例子对MongoDB没有问题,主要是为了演示数据的“格式”问题。常规$near
和other geospatial general queries are supported。但数据必须采用正确的支持格式。
所以你试图做一个空间查询?你尝试了什么?您只显示了文档,没有查询尝试,没有输出,也没有发生特定的错误。您的数据库是否设置为DocumentDB API或MongoDB API?这是一个很大的区别。我猜测MongoDB基于属性和标签,但你应该确认。 –
@DavidMakogon querry添加了 –
没有结果显示,当我尝试这 –