ZeMoon
ZeMoon

Reputation: 20284

Mongodb: Create index on array of two fields

I have a MongoDB collection in which location data is being stored as follows:

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

I need to create a 2dsphere index on these. Is there a way to combine these two separate fields into an array of the GeoJSON format?

Upvotes: 4

Views: 2057

Answers (1)

Neil Lunn
Neil Lunn

Reputation: 151170

The only valid forms for a 2dsphere index are either as a GeoJSON object or as legacy coordinate pairs. The latter form being either an array on a single field or a subdocument with "lat" and "lon" keys.

You would be better off converting this information in the document for ongoing usage, and using the GeoJSON format. The best and safest way to do this is using the 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();

You can chance that loop with eval() for a one off job, which will run the loop faster but not necessarily "safer".

Once complete it's just a matter of creating the index on the "location" field new in the document:

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

Then you can use the index in your queries.

But you will need to change the structure in the document, so do it right.

Upvotes: 7

Related Questions