我有一个非常大的数据库(大约600万行),它是从csv文件导入的。
我在看MongoDB和他们关于地理空间索引的文档。您需要将纬度和经度字段嵌入到数组中。不幸的是,我导入的结构中的字段是分开的。
“纬度”:54.770233,
“经度”:-6.537741,
是否有任何可能的方法查询数据库来计算25英里半径范围内最近的20个文档,使用纬度点54和经度-6。
我在mysql fine中创建了查询:
选择*,(3959*acos(cos(radians(54))*cos(radians(latitude
))*cos(radians(longitude
)-radians(-6))+sin(radians(54))*sin(radians(latitude
))作为距离
从表名
距离按距离排序
限制0,20
但是,我不确定在没有嵌入字段的mongo中如何做到这一点。
任何帮助都将不胜感激。
最佳答案
我认为你做不到。我会运行一个脚本来检查和更新所有文档,这需要一段时间,但不会太长。然后你可以像往常一样创建一个二维索引。
> db.test.insert({latitude:73,longitude:-47});
> db.test.insert({latitude:20,longitude:-30});
> db.test.find().forEach(function(doc) {
doc.loc = [doc.longitude, doc.latitude];
db.test.save(doc);
});
> db.test.find();
{ "_id" : ObjectId("4f7c63f117cd93783bba936d"), "latitude" : 73, "longitude" : -47, "loc" : [ 73, -47 ] }
{ "_id" : ObjectId("4f7c63f817cd93783bba936e"), "latitude" : 20, "longitude" : -30, "loc" : [ 20, -30 ] }
实际上,我想您可以使用where子句来完成它,但它不会使用任何索引。但如果是一次性查询,可能就可以了。
db.test.find("( 3959 * Math.acos(Math.cos( 54 * 0.0174532925 ) * Math.cos( this.latitude * 0.0174532925 ) * Math.cos( this.longitude * 0.0174532925 ) - (-6 * 0.0174532925)) + Math.sin( 54 * 0.0174532925 ) * Math.sin( this.latitude * 0.0174532925 )) > 25 ");
这实际上不起作用——计算结果太大了。我只是想抄你的数学,但一定有什么不对的地方。无论如何,按距离排序也是个问题。我认为第一种解决方案比较容易使用。
关于mongodb - MongoDB GeoSpatial查询没有嵌入的纬度经度字段,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10013579/