14

我有一个猫鼬模式和模型定义如下:

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);

如果我尝试:

var user = new User({ email: 'user@example.com' });

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

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

我收到错误消息:

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

尽管此模式中的位置字段不是必需的,但无论如何它似乎都是如此。我已经尝试添加default: [0,0]which 确实可以规避此错误,但它似乎有点像 hack,因为这显然不是一个好的默认值,理想情况下,架构不会要求用户始终拥有一个位置。

MongoDB / mongoose 的地理空间索引是否意味着需要索引的字段?

4

4 回答 4

46

对于 mongoose 3.8.12,您设置默认值:

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

UserSchema.index({location: '2dsphere'});
于 2014-07-14T06:32:11.003 回答
17

默认情况下,声明为数组的属性会接收一个默认的空数组以供使用。MongoDB 已经开始验证 geojson 字段,并对空数组大喊大叫。解决方法是在模式中添加一个预保存挂钩,以检查这种情况并首先修复文档。

schema.pre('save', function (next) {
  if (this.isNew && Array.isArray(this.location) && 0 === this.location.length) {
    this.location = undefined;
  }
  next();
})
于 2013-06-26T19:32:12.240 回答
2

使用地理位置创建架构并运行地理分区查询的正确方法是

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

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

如果您想运行地理分区查询,请注意这很重要,location.coordinates 中的索引 2dsphere!

于 2019-09-21T14:20:30.317 回答
0

我解决此问题的唯一方法是将索引类型从

GEO:{
    type: [Number],
    index: '2dsphere'
}

GEO:{
    type: [Number],
    index: '2d'
}

这是一场噩梦

于 2018-07-25T07:04:32.530 回答