当前位置: 首页 > 知识库问答 >
问题:

如何使用Mongoose正确更新数组中的元素

艾敏学
2023-03-14

我已经阅读了尽可能多的关于如何在MongoDB中正确更新数组中的元素的文章(比如这篇:Mongoose,更新对象数组中的值),并认为我已经遵循了所有的建议,但我仍然犯了错误,如果有人能发现我的错误,我将非常感激,因为我已经试着调试了几个小时!

我特别遇到的问题是findOneAndUpdate调用似乎只是更新“inventureItems”数组中的第一个元素,不管它是否匹配我对特定元素的查询。

我的用户集合中的数据(用户文档上的InventureItems数组中的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)似乎可以正常工作。其他两个案例似乎失败了。

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;
}

我的猫鼬呼叫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();
                    }     
                }
            );

如果你能告诉我我做错了什么,非常感谢!

共有1个答案

伯建安
2023-03-14

如果只想更新符合所有条件的子文档,则需要使用$elemMatch匹配子文档

这样地,

{
    _id: user._id,
    'itineraryItems':{
        $elemMatch:{
            iType: type,
            startDate: startDate,
            endDate: endDate,
            includeTravelTime: includeTravelTime,
            travelTimeMinutes: travelTimeMinutes,
            item: mongoose.Types.ObjectId(itemId)
        }
    }
}
 类似资料:
  • 我有以下架构 我想为创建静态方法,以便根据给定的更新 我的情况与建议的复制相似,但不相同,因为那里的家伙知道所有的,而我不知道。

  • 问题内容: 我想更新一个数组值,但我不确定要执行的正确方法,因此我尝试了以下方法,但没有为我工作。 我的模型,我模型中的子域 我的查询 谁能给我帮助。谢谢。 问题答案: 你不能同时使用 ,并 在相同的更新表达式作为嵌套的运营商。 使用更新运算符的正确语法如下: 在那里可以来自任何指定的更新列表运营商的位置。 要将一个新元素添加到数组中,只需一个 运算符即可,例如,您可以使用 update方法将修改

  • 我有一个highlight模式为:

  • 问题内容: 我读过这篇文章和同一个人的这篇文章,说您无法更新数组元素。 我还阅读了最近的一篇文章,有人说可以用某种方式完成此操作,但是我在文档中都无法获得有关stackoverflow的任何信息。 有什么办法可以解决这个问题?谢谢! 问题答案: 实际上,写这些答案的“家伙”是我:)那时,还没有一种更新数组元素的方法。只能存储数组,而 不能 更新数组成员。 现在,在更新文档时,您可以将第二个参数传递

  • 错误消息:我想它说我的输入是int,即使它们被设置为String。我该怎么办? RPSL. java: 57:错误:不兼容类型:字符串不能转换为int结果[user武器][computer武器]=possibleTie; RPSL。java:57:错误:不兼容的类型:无法将字符串转换为int 结果[UserBearm][ComputerBearm]=possibleTie;

  • 我有一个以下格式的mongodb文档。如何基于父属性_id更新数组中第一个元素的rolename字段。