3

我有一个从 csv 文件导入的非常大的数据库(约 600 万行)。我正在查看 MongoDB 和他们关于 GeoSpatial indexing 的文档。您需要将纬度和经度字段嵌入到数组中。不幸的是,我导入的结构具有单独的字段。

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

是否有任何可能的方法来查询数据库以使用纬度 54 和经度 -6 计算 25 英里半径内的 20 个最近的文档。

我在 MySQL 中很好地创建了查询:

选择 * , ( 3959 * ACOS( COS( RADIANS( 54 ) ) * COS( RADIANS( latitude) ) * COS( RADIANS( longitude) - RADIANS( -6 ) ) + SIN( RADIANS( 54 ) ) * SIN( RADIANS( latitude) ) ) ) AS distance FROM table_name HAVING distance <25 ORDER BY distance LIMIT 0 , 20

但是,我不确定如何在没有嵌入字段的情况下在 Mongo 中执行此操作。

任何帮助将非常感激。

4

1 回答 1

3

我不认为你可以。我会运行一个脚本来检查和更新所有文档,这需要一段时间但不会太长。然后你可以像往常一样创建一个二维索引。

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

这实际上不起作用——计算的结果太大了。我只是想复制你的数学,但一定有什么不对劲。无论如何,按距离排序也将是一个问题。我认为第一个解决方案更容易使用。

于 2012-04-04T15:11:42.063 回答