【问题标题】:Mongodb: Create index on array of two fieldsMongodb:在两个字段的数组上创建索引
【发布时间】:2015-03-01 09:09:35
【问题描述】:

我有一个 MongoDB 集合,其中存储位置数据如下:

{
    ...
    longitude: "-73.985679",
    latitude: "40.75003",
    ...
}

我需要在这些上创建一个 2dsphere 索引。有没有办法将这两个单独的字段组合成一个 GeoJSON 格式的数组?

【问题讨论】:

    标签: mongodb indexing mongodb-query geospatial


    【解决方案1】:

    2dsphere 索引的唯一有效形式是作为 GeoJSON 对象或作为旧坐标对。后一种形式是单个字段上的数组或带有“lat”和“lon”键的子文档。

    您最好将文档中的这些信息转换为持续使用,并使用 GeoJSON 格式。最好和最安全的方法是使用Bulk Operations API:

    var bulk = db.collection.initializeOrderedBulkOp();
    var counter = 0;
    
    db.collection.find().forEach(function(doc) {
         bulk.find({ "_id": doc._id }).updateOne({
            "$set": {
                "location": {
                    "type": "Point",
                    "coordinates": [ doc.longitude, doc.latitude ]
                }
            },
            "$unset": {  "longitude": 1, "latitude": 1 } 
         });
    
         counter++;
         if ( counter % 1000 == 0 ) {
             bulk.execute();
             bulk = db.collection.initializeOrderedBulkOp();
         }
    
    })
    
    if ( counter % 1000 != 0 )
        bulk.execute();
    

    您可以使用eval() 进行一次一次性的循环,这将更快地运行循环,但不一定“更安全”。

    一旦完成,只需在文档中新的“位置”字段上创建索引:

    db.collection.ensureIndex({ "location": "2dsphere" })
    

    然后您可以在查询中使用索引。

    但是您需要更改文档中的结构,所以请正确操作。

    【讨论】:

    • 谢谢!我想转型是唯一的方法。填充此数据的 Web 应用程序将位置存储在单独的字段中。有没有一种方法可以在创建新文档时从 MongoDB 本身重构数据?
    • @ZeMoon 当然,任何创建具有原始结构的文档的代码都应该更改,因此您必须解决这个问题,这应该是一个相当微不足道的更改。人们需要习惯结构化文档方法而不是 RDBMS 的“表格”方法,这似乎就是其中之一。
    • 很好。再次感谢!
    • @ZeMoon 你可以用任何你想要的语言编写代码。每个可用的驱动程序都具有支持批量操作 API 甚至只是基本循环和更新的功能。
    • 很好的解决方案,谢谢。注意未设置行上的“latitude”应该是“latitude”,最后的检查应该是if ( counter % 1000 != 0)(抱歉我不能编辑,因为显然我必须更改6个字符)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    • 2013-06-22
    相关资源
    最近更新 更多