我有一个mongoose模式和模型定义如下:
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]
,它确实绕过了这个错误,但是它似乎有点像黑客,因为这显然不是一个好的默认值,理想情况下,架构不需要用户始终拥有一个位置
使用MongoDB / mongoose的地理空间索引是否意味着需要索引的字段?
答案 0 :(得分:38)
对于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'});
答案 1 :(得分:17)
默认情况下,声明为数组的属性会接收要使用的默认空数组。 MongoDB已经开始验证geojson字段并对空数组大喊大叫。解决方法是在架构中添加一个预保存挂钩,以检查此场景并首先修复文档。
schema.pre('save', function (next) {
if (this.isNew && Array.isArray(this.location) && 0 === this.location.length) {
this.location = undefined;
}
next();
})
答案 2 :(得分:0)
我解决此问题的唯一方法是将索引类型从
更改GEO:{
type: [Number],
index: '2dsphere'
}
到
GEO:{
type: [Number],
index: '2d'
}
那是一场噩梦
答案 3 :(得分:0)
使用地理位置创建架构并运行geospartial查询的正确方法是
var UserSchema = new Schema({
location: {
type: {
type: String,
default: 'Point',
},
coordinates: {
type: [Number]
}
}
});
UserSchema.index({location.coordinates: '2dsphere'});
并且当您开始节点项目时,请不要忘记将索引创建为
YourScema.createIndexes();
请注意,这很重要,因为索引2dsphere在 location.coordinates,如果您想运行geospartial查询!