Search code examples
javascriptnode.jsmongodbmongoosegeojson

MongoDB Malformed Geometry with geojson


Using MongoDB v2.6.5

When I attempt to save a geojson document into the db I receive the following error:

name: 'MongoError',
  code: 16755,
  err: 'insertDocument :: caused by :: 16755 Can\'t extract geo keys from object, malformed geometry?: { _id: ObjectId(\'55271b90d075728028d4c9e1\'), ..., location: [ { _id: ObjectId(\'55271b90d075728028d4c9e3\'), loc: { type: "Point", coordinates: [ -105.01621, 39.57422 ] } } ] } ], status: [ "lead" ], created: new Date(1428626320406), lastName: "Doe", firstName: "John", __v: 0 }' }

I'm attempting to insert a Point into the table with a 2dsphere index, all managed through MongooseJS as shown below.

var GeoAddressSchema = new Schema({
    // Only holds points.
    loc: {
        type: { type: String },
        coordinates: []
    }
});


var Lead = new Schema({
    // Other fields  ...
    location: [GeoAddressSchema],
    // ...
});

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

The geojson that is being saved:

{ type: "Point", coordinates: [ -111.855211, 33.58513 ] }

The geojson is valid according to: http://geojsonlint.com/ if I wrap the fields in quotes, but I should not need to do that (and cannot for Mongo afaik).

Anyone have any idea why this would fail? It looks correct.

Reference links

MongoDB GeoJSON: http://docs.mongodb.org/manual/reference/geojson/

MongoDB 2dSphere: http://docs.mongodb.org/manual/core/2dsphere/


Solution

  • First observation: you need not introduce the loc path in the location structure.

    Further, you need not even define a separate schema for your location field in the Lead schema.

    Try this:

    var Lead = new Schema({
      // Other fields  ...
      location: {
        type: {
          type: 'String',
          default: 'Point'  // and optionally skip including `type: String` everywhere
        },
        coordinates: {
          type: [Number]
        }
      },
      // More fields ...
    });
    
    LeadAddressSchema.index({ location: '2dsphere' });
    

    Another problem I faced was that the 2dsphere index gets messed up, when figuring and testing out solutions. So try dropping the index, or even better the collection after you make structural changes to the schema.

    > db.lead.drop();  // on the mongo console`