如何使用 Mongoose 正确更新数组中的元素
Posted
技术标签:
【中文标题】如何使用 Mongoose 正确更新数组中的元素【英文标题】:How to correctly update an element in an array using Mongoose 【发布时间】: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
谢谢温弗里德。我不打算这样做,但很高兴知道这种语法 - 非常感谢!
【参考方案1】:
如果您只想更新匹配所有条件
的subdocument
,则需要使用$elemMatch
匹配您的subdocument
这样,
_id: user._id,
'itineraryItems':
$elemMatch:
iType: type,
startDate: startDate,
endDate: endDate,
includeTravelTime: includeTravelTime,
travelTimeMinutes: travelTimeMinutes,
item: mongoose.Types.ObjectId(itemId)
【讨论】:
谢谢!我刚刚修改了我的代码并且它正在工作。非常感谢!以上是关于如何使用 Mongoose 正确更新数组中的元素的主要内容,如果未能解决你的问题,请参考以下文章