52

I'm just trying to get a simple near query working. Here's a sample of my document.

{"point": 
  {"type": "Point", 
     "coordinates": [30.443902444762696, -84.27326978424058]}, 
   "created_on": {"$date": 1398016710168}, 
   "radius": 180, 
   "user": {"$oid": "53543188eebc5c0cc416b77c"}, 
   "_id": {"$oid": "53544306eebc5c0ecac6cfba"}, 
   "expires_on": {"$date": 1399831110168}
}

and with mongod I tried the command:

db.bar.find({point: {$near: [-84.26060492426588, 30.45023887165371]}});

but I get this error:

error: { "$err" : "Unable to execute query: error processing query: ns=foo.bar skip=0\nTree: GEONEAR field=point maxdist=1.79769e+308 isNearSphere=0 || First: notFirst: full path: point\nSort: {}\nProj: {}\n planner returned error: unable to find index for $geoNear query", "code" : 17007 }

Maybe my google fu is not so sharp today but I couldn't find anything. Also, I ran the ensure index command. My intention is that these are map locations.

db.bar.ensureIndex({a:1});
db.bar.ensureIndex({geo:"2d"});
styvane
  • 59,869
  • 19
  • 150
  • 156
frankV
  • 5,353
  • 8
  • 33
  • 46

7 Answers7

93

Few problems, you created your indexes on the foo collection of the foo database, but are querying the bar collection. You need to be on the correct collection.

Reading the document you have inserted you need to add a "2dsphere" index to support the geoJson objects. This index needs to be on the "point" element of your documents, so try

db.bar.createIndex({point:"2dsphere"});

You can then query as follows by providing a geoJson obj for the query:

db.bar.find(
   { point :
       { $near :
          {
            $geometry : {
               type : "Point" ,
               coordinates : [-84.27326978424058, 30.443902444762696] },
            $maxDistance : 1
          }
       }
    }
)
Yan Foto
  • 10,850
  • 6
  • 57
  • 88
daveh
  • 3,586
  • 1
  • 20
  • 13
  • 6
    Great, solved my issue using: `db..ensureIndex({point:"2dsphere"});` – AfromanJ Jun 20 '14 at 08:32
  • 1
    Note that sine `3.0.0` `ensureIndex` [has been deprecated](https://docs.mongodb.com/manual/reference/method/db.collection.ensureIndex/) and is an alias for `createIndex` (answer edited accordingly) – Yan Foto Dec 14 '16 at 14:14
  • any idea about this in compass: `geoNear command failed: { operationTime: Timestamp(1536208908, 1), ok: 0.0, errmsg: "2dsphere index must have spherical: true", code: 17301, codeName: "Location17301", $clusterTime: { clusterTime: Timestamp(1536208908, 1), ` for `{ "near": { "type": "Point", "coordinates": [ -73.99279 , 40.719296 ] }, "distanceField": "distance" }` – Hassan Faghihi Sep 06 '18 at 04:42
  • @deadManN add `spherical: true` after `distanceField: 'distance'` . This worked for me . – Daksh Jul 31 '19 at 08:30
  • Where i want to place this line : `db.bar.createIndex({point:"2dsphere"});` ?? – Sanjayrajsinh Jul 25 '21 at 08:20
12
db.prod.createIndex({ "location": "2d" })

This solved for the same issue for me.

Where prod is my collection name and location is name of column which stores geo location (GeoPoint)

Some discussion about the same can be found here

Krish Nakum R
  • 505
  • 1
  • 8
  • 19
8

So there seems to be a couple of things wrong here:

  • From the data you are showing and also your query information the relevant information is contained under the field point and in GeoJSON format. Your index creation:
db.foo.createIndex({geo: "2d"})

Does not "fail" because there presently isn't a field called "geo" and the field with the data should have been in that place. If you had used "point" instead, which is the correct field, then you would have received an error telling you that this type of index is invalid for the GeoJSON data. You need a "2dsphere" index:

db.points.createIndex({ "point": "2dsphere" })
  • Extending the same problem, again the data is in GeoJSON format and the form of the query is that for a legacy coordinate pair. You need to change the query arguments so that no longer fails:
db.points.find({point: {
    $near: {
        $geometry:{ 
            type: "Point", 
            coordinates: [-84.26060492426588, 30.45023887165371]
        }
    }
}})

See the documentation for $near

George Katsanos
  • 13,524
  • 16
  • 62
  • 98
Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
  • Thank you for the detailed explanation. With your answer, I noticed what was failing for me, I wasn't pointing to the correct property where I was saving the path to create the index. – Carlos Bensant Aug 09 '23 at 23:36
3

In addition to the answers above, if you've already tried to create an Index and got some syntax or field wrong, you can run

db.<yourcollection>.dropIndexes(); To clean up all indexes and re-create them properly.

Also, the index should be created on the parent of "coordinates", not on coordinates itself:

{
   "_id": 59ac03d168eaaa14c2a57a00",
   "location":{
      "type":"Point",
      "coordinates":[
         131.6667,
         57.8368
      ]
   },
   "age":53,
   "username":"Brandi_Greenfelder"
}

db.<yourcollection>.createIndex({ location: '2dsphere' });

Attention, there is "2d" and "2dsphere", use the second as it's the new thing.

George Katsanos
  • 13,524
  • 16
  • 62
  • 98
1

If you're using mongoose to connect, this would be right answer:

db.collections.<yourcollection>.createIndex({ location : "2dsphere" })

Notice there is a "collections" property before collection itself. If it's not working, check db object in console.log:

console.log(db)
RomanistHere
  • 795
  • 7
  • 17
0

If anybody is migrating from spring-boot-starter-data-mongodb 2 to 3

They desactivated the autoconfiguration of indexes by default, which could cause this error of 'unable to find index for $geoNear query'

@Configuration
public class Config extends AbstractMongoClientConfiguration {

    @Override
    protected boolean autoIndexCreation() {
        return true;
    }
    // ...
}
user1864070
  • 173
  • 1
  • 10
0

In my case, I had it all (valid GeoJSON, 2dsphere index) and the error was still appearing. The problem was, that I failed to specify the same 2dsphere value for index in a Schema definition, when creating/saving new object:

// Geo index for new object
const boxSchema = new Schema<IBoxRecord>({
  id: { type: Number, required: true },
  name: { type: String, index: true, required: true },
  location: { 
    type: Object,
    index: "2dsphere", // <--- previously set to `true` by mistake
    require: true 
  }
});

...

// index existing collection
await BoxRecord.collection.createIndex({ location: "2dsphere" });
igraczech
  • 2,408
  • 3
  • 25
  • 30