$and combined with 2dsphere in mongo/mongoose

I'm trying to get this code to work (node+mongoose)

model.find({
        $and: [
            { 'location': { $near: { $geometry: {type: 'Point', coordinates: [lat, long]}  }, $maxDistance: 1000 }},
            {'status': { $size: 1 }}
        ]
    },

and keep on getting

can't find any special indices: 2d (needs index), 2dsphere (needs index), for: { $and: [ { location: { $near: { $geometry: { type: "Point", coordinates: [ 12.5386, 41.884 ] } }, $maxDistance: 1000 } }, { status: { $size: 1 } } ] }

i do have my indexes in place with mongo

{
    "location" : "2dsphere"
}

what am i missing? many thanks.

EDIT : adding document structure

{
    "name" : "Frag",
    "desc" : "Frag",
    "host" : ObjectId("534047663164711f7e7a952f"),
    "_id" : ObjectId("535d7d8b454017f874de2d42"),
    "status" : [ 
        {
            "state" : "created",
            "_id" : ObjectId("535d7d8b454017f874de2d43"),
            "date" : ISODate("2014-04-27T21:58:35.406Z")
        }
    ],
    "users" : [ 
        ObjectId("534047663164711f7e7a952f")
    ],
    "location" : [ 
        32.0652823, 
        34.7767135
    ],
    "__v" : 0
}

Upvotes: 0

Views: 656

Answers (1)

Neil Lunn
Neil Lunn

Reputation: 151112

You are doing something wrong here in that you are specifying GeoJSON co-ordinate mapping for something you actually have defined as "legacy co-ordinate pairs" and there is a big difference between the two.

Certainly what you should be doing (your data on my collection called docs):

db.docs.find({ 
    "location": { 
        "$near": [12.5386, 41.884], 
        "$maxDistance": 1000
    },
    "status": { "$size": 1 }
})

But this is failing unless I actually change the index type to "2d" instead:

db.docs.dropIndexes();
db.docs.ensureIndex({ "location": "2d" })

Then you get the result of your document as you are expecting.

This is by design as a "2dsphere" index is designed for data in GeoJSON format, from the documentation:

The $near operator requires a geospatial index: a 2dsphere index for GeoJSON points; a 2d index for legacy coordinate pairs. By default, queries that use a 2d index return a limit of 100 documents; however you may use limit() to change the number of results.

If you want a "2dsphere" index then your co-ordinates data needs to change:

    "loc" : {
        "type" : "Point",
        "coordinates" : [
            32.0652823, 
            34.7767135
        ]
    }

But the immediate "workaround" is clearly to use a "2d" index instead, and of course change your syntax as I have shown.

Upvotes: 1

Related Questions