【发布时间】:2020-05-23 14:43:42
【问题描述】:
我已经阅读了尽可能多的关于如何正确更新 MongoDB 中数组中的元素的文章(例如这篇文章:Mongoose, update values in array of objects),并认为我已经遵循了所有建议,但我仍然得到这个错误,如果有人能发现我的错误,将不胜感激,因为我已经尝试调试了好几个小时!
我特别遇到的问题是 findOneAndUpdate 调用似乎只是更新“itineraryItems”数组中的第一个元素,无论它是否匹配我对特定元素的查询。
我的用户集合中的数据(用户文档上的 itineraryItems 数组中的 2 个数组元素):
db.users.find({_id: ObjectId("5dd65ce7998d626a2c71a547"), {itineraryItems: 1})
{ "_id" : ObjectId("5dd65ce7998d626a2c71a547"),
"itineraryItems" : [
{ "_id" : ObjectId("5e3d5a301b65f3f9fd1621f8"),
"iType" : "event",
"startDate" : ISODate("2020-02-07T11:00:00Z"),
"endDate" : ISODate("2020-02-07T13:00:00Z"),
"includeTravelTime" : false,
"travelTimeMinutes" : 0,
"item" : null,
"event" : ObjectId("5dea66c182d9ac6fb4c6f36e")
},
{ "_id" : ObjectId("5e3d5a341b65f3f9fd1621ff"),
"iType" : "item",
"startDate" : ISODate("2020-02-07T11:00:00Z"),
"endDate" : ISODate("2020-02-07T13:00:00Z"),
"includeTravelTime" : false,
"travelTimeMinutes" : 0,
"item" : ObjectId("5e29df801f026697b71f7f48"),
"event" : null
}
]
}
我的查询构建功能: 请注意,满足第一个 if 语句的查询(即我为数组中的元素传入一个已知的 id)似乎工作正常。其他 2 个案例似乎失败了。
function getUpdateItineraryElementQuery(user, id, type, startDate, endDate, includeTravelTime, travelTimeMinutes, itemId) {
let query = {};
if (
(id!=null) &&
(id!='not_set')
) {
query = {
_id: user._id,
'itineraryItems._id': mongoose.Types.ObjectId(id)
};
} else {
if (type==='event') {
query = {
_id: user._id,
'itineraryItems.iType': type,
'itineraryItems.startDate': startDate,
'itineraryItems.endDate': endDate,
'itineraryItems.includeTravelTime': includeTravelTime,
'itineraryItems.travelTimeMinutes': travelTimeMinutes,
'itineraryItems.event': mongoose.Types.ObjectId(itemId)
};
} else {
if (type==='item') {
query = {
_id: user._id,
'itineraryItems.iType': type,
'itineraryItems.startDate': startDate,
'itineraryItems.endDate': endDate,
'itineraryItems.includeTravelTime': includeTravelTime,
'itineraryItems.travelTimeMinutes': travelTimeMinutes,
'itineraryItems.item': mongoose.Types.ObjectId(itemId)
};
}
}
}
return query;
}
我的 Mongoose 调用 findOneAndUpdate:
User.findOneAndUpdate(
query,
{
'itineraryItems.$.startDate': dtNewStartDate,
'itineraryItems.$.endDate': dtNewEndDate,
'itineraryItems.$.includeTravelTime': newIncludeTravelTime,
'itineraryItems.$.travelTimeMinutes': newTravelTimeMinutes
// eslint-disable-next-line no-unused-vars
}, (err, doc) => {
if (err) {
// not found?
res.sendStatus(404).end();
} else {
// ok
res.sendStatus(200).end();
}
}
);
如果你能告诉我我做错了什么,非常感谢!
【问题讨论】:
-
如果你想更新数组中的 all 元素,那么语法应该是
itineraryItems.$[].startDate而不是itineraryItems.$.startDate -
谢谢温弗里德。我不打算这样做,但很高兴知道这种语法 - 非常感谢!