Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does applying a 2dsphere index on a mongoose schema force the location field to be required?

I have a mongoose schema and model defined as follows:

var mongoose = require('mongoose')
  , Schema = new mongoose.Schema({
      email: {
        index: {
          sparse: true,
          unique: true
        },
        lowercase: true,
        required: true,
        trim: true,
        type: String
      },
      location: {
        index: '2dsphere',
        type: [Number]
      }
    })
  , User = module.exports = mongoose.model('User', Schema);

If I attempt:

var user = new User({ email: '[email protected]' });

user.save(function(err) {
  if (err) return done(err);

  should.not.exist(err);
  done();
});

I receive the error message:

MongoError: Can't extract geo keys from object, malformed geometry?:{}

Despite the location field in this schema not being required, it seems to be acting as such anyways. I have tried adding default: [0,0] which does circumvent this error, however it seems like a bit of a hack, as this is clearly not a good default, and ideally the schema would not require the user to have a location at all times.

Do geospatial indexes with MongoDB / mongoose imply that the field being indexed is required?

like image 567
Nik Macintosh Avatar asked May 05 '13 20:05

Nik Macintosh


People also ask

What is the purpose of using an index in a Mongoose schema?

Indexes support the efficient execution of queries in MongoDB. Without indexes, MongoDB must perform a collection scan, i.e. scan every document in a collection, to select those documents that match the query statement.

What is 2dsphere index in MongoDB?

A 2dsphere index supports queries that calculate geometries on an earth-like sphere. 2dsphere index supports all MongoDB geospatial queries: queries for inclusion, intersection and proximity. For more information on geospatial queries, see Geospatial Queries.

What is required true in Mongoose schema?

Mongoose has several built-in validators. All SchemaTypes have the built-in required validator. The required validator uses the SchemaType's checkRequired() function to determine if the value satisfies the required validator.

How does Mongoose schema work?

With Mongoose, you would define a Schema object in your application code that maps to a collection in your MongoDB database. The Schema object defines the structure of the documents in your collection. Then, you need to create a Model object out of the schema. The model is used to interact with the collection.


2 Answers

The correct way to create a schema with geolocation and run geospartial queries was

var UserSchema = new Schema({
  location: {
    type: {
      type: String,
      enum: ["Point"], // 'location.type' must be 'Point'
    },
    coordinates: {
      type: [Number]
    }
  }
});

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

Be careful this is important to do, the index 2dsphere in the location.coordinates, if you want to run geospartial queries!

like image 148
Costas Bakoulias Avatar answered Sep 27 '22 22:09

Costas Bakoulias


For mongoose 3.8.12, you set the default value:

var UserSchema = new Schema({
  location: {
    type: {
      type: String,
      enum: ['Point'],
      default: 'Point',
    },
    coordinates: {
      type: [Number],
      default: [0, 0],
    }
  }
});

UserSchema.index({location: '2dsphere'});
like image 25
user3160143 Avatar answered Sep 27 '22 20:09

user3160143