2012-04-04 33 views
3

我有一个非常大的数据库(约600万行)从csv文件导入。 我在查看MongoDB及其关于GeoSpatial索引的文档。您需要将纬度和经度字段嵌入到数组中。不幸的是,我输入的结构有单独的字段。MongoDB地理空间查询没有嵌入纬度经纬度字段

“纬度”:54.770233, “东经”:-6.537741,

有查询数据库,计算25英哩半径之内二十最近的文档中使用的54和经度纬度点的任何可能的方式的-6。

我创建的查询在MySQL的罚款:

SELECT *,(3959 * ACOS(COS(RADIANS(54))* COS(RADIANS(latitude))* COS(RADIANS(longitude) - RADIANS( - 6))+ SIN(RADIANS(54))* SIN(RADIANS(latitude))))AS距离 FROM TABLE_NAME HAVING距离 ORDER BY距离 LIMIT 0,20

然而,我不确定如何在没有嵌入字段的Mongo中执行此操作。

任何帮助将不胜感激。

回答

3

我不认为你可以。我会运行脚本来完成并更新所有文档,这需要一段时间但不会太长。然后你可以按照惯例创建一个2d索引。

> 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 "); 

这实际上并不奏效 - 计算结果太大。我只是想复制你的数学,但一定是不对的。无论如何,按距离排序也是一个问题。我认为第一个解决方案比较容易处理。

+0

运行更新所有文档的正确脚本是什么? – user1313125 2012-04-11 13:13:30

+0

这是find()。forEach('...在我的示例代码中的部分。 – 2012-04-11 13:26:32

+0

谢谢,我正在运行该脚本。不幸的是,它看起来可能需要相当长的一段时间。在不同的数据库上进行测试后。 – user1313125 2012-04-12 13:56:41