3

I have a mongodb collection with a defined schema, and I updated this schema to include lat/lon coordinates.

old version:

var schema = mongoose.Schema({
    id: String,
    name: String,
    address: String,
    city: String,
    zip: String,
    country: String,
    phoneNumber: String,
    mobile: String,
    website: String,
    email: String,
});

new version

var schema = mongoose.Schema({
    id: String,
    name: String,
    address: String,
    city: String,
    zip: String,
    country: String,
    phoneNumber: String,
    mobile: String,
    website: String,
    email: String,
    location: GeoJSON.Point
});

schema.index({ location: '2dsphere' });

GEOJSON.Point comes from mongoose-geojson-schema and looks like this:

GeoJSON.Point = {
  'type'     : { type: String, default: "Point" },
  coordinates: [
    {type: "Number"}
  ]
}

The collection already contained data before I added the location property.

Apparently what happens now is that for some reason mongodb uses { coordinates: [], type: "Point" } as default value for the existing documents, and I get errors like these:

 MongoError: Can't extract geo keys: { _id: ObjectId('5637ea3ca5b2613f37d826f6'), ...
 Point must only contain numeric elements 

I have looked at how to specify a default value in a schema, but I see no way of setting the value to null in case of a GeoJSON.Point data type.

I also tried

db.collection.update({},{$set:{location:null},{multi:true})

but that didn't seem to help either.

Is it because of the index on the location?

Joris Mans
  • 6,024
  • 6
  • 42
  • 69
  • The Mongoose 3.6 [release notes](https://github.com/Automattic/mongoose/wiki/3.6-Release-Notes#geojson-support-mongodb--24) suggest that you should use arrays-of-Numbers as type. Where's `GeoJSON.Point` coming from? – robertklep Dec 01 '15 at 15:25
  • I edited my question with that extra info – Joris Mans Dec 01 '15 at 16:18

2 Answers2

0

I think you need to upgrade GeoJSON.Point to a sub document with a proper schema:

GeoJSON.Point = new mongoose.Schema({
  'type'     : { type: String, default: "Point" },
  coordinates: [ { type: "Number" } ]
});

Combined with the minimize option, which it enabled by default, this will make Mongoose only save the location property if it is actually set.

robertklep
  • 198,204
  • 35
  • 394
  • 381
0

I would suggest you to not use GeoJSON.Point as a schema type. Just use mixed object type and everything will work properly.

location: Schema.Types.Mixed
Karlen
  • 1,294
  • 13
  • 20