猫鼬 setDefaultsOnInsert 和 2dsphere 索引不工作
Mongoose setDefaultsOnInsert and 2dsphere index not working
当使用 findOneAndUpdate
和 upsert 并且 setDefaultsOnInsert
设置为 true 时,我在尝试向我的数据库中插入新用户时遇到问题。我想要做的是设置以下架构的默认值:
var userSchema = new mongoose.Schema({
activated: {type: Boolean, required: true, default: false},
facebookId: {type: Number, required: true},
creationDate: {type: Date, required: true, default: Date.now},
location: {
type: {type: String},
coordinates: []
},
email: {type: String, required: true}
});
userSchema.index({location: '2dsphere'});
findOneAndUpdate
代码:
model.user.user.findOneAndUpdate(
{facebookId: request.params.facebookId},
{
$setOnInsert: {
facebookId: request.params.facebookId,
email: request.payload.email,
location: {
type: 'Point',
coordinates: request.payload.location.coordinates
}
}
},
{upsert: true, new: true, setDefaultsOnInsert: true}, function (err, user) {
if (err) {
console.log(err);
return reply(boom.badRequest(authError));
}
return reply(user);
});
如您所见,我还存储了用户的纬度和经度,这就是问题开始的地方。当 findOneAndUpdate
被调用时,我得到这个错误:
{ [MongoError: exception: Cannot update 'location' and 'location.coordinates' at the same time]
name: 'MongoError',
message: 'exception: Cannot update \'location\' and \'location.coordinates\' at the same time',
errmsg: 'exception: Cannot update \'location\' and \'location.coordinates\' at the same time',
code: 16836,
ok: 0 }
当我删除 2dsphere 索引和所有与位置相关的代码时,它确实设置了我的创建日期。我做错了什么?
setDefaultsOnInsert
选项使用 $setOnInsert
运算符来执行其功能,这看起来与您自己使用 $setOnInsert
设置 location
冲突。
解决方法是删除 setDefaultsOnInsert
选项并将其全部放在您自己的 $setOnInsert
运算符中:
model.user.user.findOneAndUpdate(
{facebookId: request.params.facebookId},
{
$setOnInsert: {
activated: false,
creationDate: Date.now(),
email: request.payload.email,
location: {
type: 'Point',
coordinates: request.payload.location.coordinates
}
}
},
{upsert: true, new: true},
function (err, user) {
if (err) {
console.log(err);
return reply(boom.badRequest(authError));
}
return reply(user);
});
其中一位开发人员在 github 上回复了我的问题,并将其添加为 4.0.8 版本的里程碑,这是他的解决方法:
$setOnInsert: {
facebookId: request.params.facebookId,
email: request.payload.email,
'location.type': 'Point',
'location.coordinates': request.payload.location.coordinates
}
他的解决方案对我不起作用,我收到以下错误:
{ [MongoError: exception: insertDocument :: caused by :: 16755 Can't extract geo keys from object, malformed geometry?: { _id: ObjectId('559024a0395dd599468e4f41'), facebookId: 1.020272578180189e+16, location: { coordinates: [], type: "Point" }, email: "druwe.jeroen@gmail.com", gender: "male", lastName: "Druwé", firstName: "Jeroen", __v: 0, activated: false, creationDate: new Date(1435509921264), familyDetails: { children: [] } }]
当使用 findOneAndUpdate
和 upsert 并且 setDefaultsOnInsert
设置为 true 时,我在尝试向我的数据库中插入新用户时遇到问题。我想要做的是设置以下架构的默认值:
var userSchema = new mongoose.Schema({
activated: {type: Boolean, required: true, default: false},
facebookId: {type: Number, required: true},
creationDate: {type: Date, required: true, default: Date.now},
location: {
type: {type: String},
coordinates: []
},
email: {type: String, required: true}
});
userSchema.index({location: '2dsphere'});
findOneAndUpdate
代码:
model.user.user.findOneAndUpdate(
{facebookId: request.params.facebookId},
{
$setOnInsert: {
facebookId: request.params.facebookId,
email: request.payload.email,
location: {
type: 'Point',
coordinates: request.payload.location.coordinates
}
}
},
{upsert: true, new: true, setDefaultsOnInsert: true}, function (err, user) {
if (err) {
console.log(err);
return reply(boom.badRequest(authError));
}
return reply(user);
});
如您所见,我还存储了用户的纬度和经度,这就是问题开始的地方。当 findOneAndUpdate
被调用时,我得到这个错误:
{ [MongoError: exception: Cannot update 'location' and 'location.coordinates' at the same time]
name: 'MongoError',
message: 'exception: Cannot update \'location\' and \'location.coordinates\' at the same time',
errmsg: 'exception: Cannot update \'location\' and \'location.coordinates\' at the same time',
code: 16836,
ok: 0 }
当我删除 2dsphere 索引和所有与位置相关的代码时,它确实设置了我的创建日期。我做错了什么?
setDefaultsOnInsert
选项使用 $setOnInsert
运算符来执行其功能,这看起来与您自己使用 $setOnInsert
设置 location
冲突。
解决方法是删除 setDefaultsOnInsert
选项并将其全部放在您自己的 $setOnInsert
运算符中:
model.user.user.findOneAndUpdate(
{facebookId: request.params.facebookId},
{
$setOnInsert: {
activated: false,
creationDate: Date.now(),
email: request.payload.email,
location: {
type: 'Point',
coordinates: request.payload.location.coordinates
}
}
},
{upsert: true, new: true},
function (err, user) {
if (err) {
console.log(err);
return reply(boom.badRequest(authError));
}
return reply(user);
});
其中一位开发人员在 github 上回复了我的问题,并将其添加为 4.0.8 版本的里程碑,这是他的解决方法:
$setOnInsert: {
facebookId: request.params.facebookId,
email: request.payload.email,
'location.type': 'Point',
'location.coordinates': request.payload.location.coordinates
}
他的解决方案对我不起作用,我收到以下错误:
{ [MongoError: exception: insertDocument :: caused by :: 16755 Can't extract geo keys from object, malformed geometry?: { _id: ObjectId('559024a0395dd599468e4f41'), facebookId: 1.020272578180189e+16, location: { coordinates: [], type: "Point" }, email: "druwe.jeroen@gmail.com", gender: "male", lastName: "Druwé", firstName: "Jeroen", __v: 0, activated: false, creationDate: new Date(1435509921264), familyDetails: { children: [] } }]