我有两个架构。一个是这样的。
var tripSchema = mongoose.Schema({
distance :{
type: 'Number',
required: true
},
source : {
latitude: {
type: 'Number',
required: true
},
longitude: {
type: 'Number',
required: true
}
},
destination: {
latitude: {
type: 'Number',
required: true
},
longitude: {
type: 'Number',
required: true
}
},
tripON:{
type : 'Boolean',
default: false
}
}
和另一个这样的架构
var userTrips = mongoose.Schema({
userId: {
type: Schema.Types.ObjectId,
required: true,
ref : 'users'
},
trips : [tripSchema]
});
现在通过使用一些查询我已经创建了这样的文档。
"_id" : ObjectId("561bf7c0a3724f066b834985"),
"userId" : ObjectId("561bda2117a4b49362b14dfb"),
"deviceId" : "58",
"carId" : "abcd123",
"trips" : [
{
"startTime" : ISODate("2015-05-20T15:28:55Z"),
"_id" : ObjectId("561ea4df42d8b60947a79b4b"),
"tripON" : true,
"source" : {
"latitude" : 13.07,
"longitude" : 77.6181319
}
}]
现在将tripON的值更改为false我写了这个查询并介意你我不想upsert但严格更新。
Trip.update({ userId: deviceUserCarMap.userId, deviceId: deviceId, carId: deviceUserCarMap.carId},
{ $set: { 'trips.$.destination': { latitude: lat, longitude: lng }, 'trips.$.tripON': false} }, null,
function (err, trip) {
if (err) {
console.log(err);
}
else {
console.log('Trip End Saved');
userCache.toggleTripFlag(userIndex);
console.log(trip);
}
});
我得到一个错误。
[MongoError: The positional operator did not find the match needed from the query. Unexpanded update: trips.$.destination]
name: 'MongoError',
message: 'The positional operator did not find the match needed from the query. Unexpanded update: trips.$.destination',
driver: true,
index: 0,
code: 16837,
errmsg: 'The positional operator did not find the match needed from the query. Unexpanded update: trips.$.destination' }
我该如何解决?
编辑:
即使在提供此查询后:db.trips.findOne({'trips.0._id' : ObjectId("561ea4df42d8b60947a79b4b") })
我在userTrips中获取tripSchema数组的所有元素,而不只是一个。为什么呢?
答案 0 :(得分:0)
终于找到了答案......虽然不是全部。但这是来自评论中给出的链接的方法。
“$运算符可以更新匹配的第一个数组元素 使用$ elemMatch()运算符指定的多个查询条件。“
“与更新操作一起使用时,例如db.collection.update()和 db.collection.findAndModify(),位置$运算符充当a 与查询文档匹配的第一个元素的占位符。“
“位置$运算符不能用于遍历的查询 多个数组...因为$占位符的替换是 单个值“
所以你必须在MongoDB中编写一个脚本。现在该如何写。
db = connect("localhost:27017/metaiot")
; load(fullpath/data/db/scripts/myScript.js)
。就我而言,它看起来像load("/home/oroborus/data/db/scripts/myScript.js")
。如果成功加载将返回true。如果您收到错误,则表示您的文件路径错误。请提供完整的路径名称。即使mongo文档说相对路径工作也不要听。使用绝对路径。我通过反复试验发现了这一点。
db = connect("localhost:27017/metaiot");
var numbers = db.trips.find({trips :{$elemMatch : {"tripON":false}}});
numbers.forEach(function(setter)
{ for(var index in setter.trips){
print(setter.trips[index]._id)
}
});
现在做你喜欢做的事。我花了3个小时来搞清楚这一点。但它是值得的。