首页 > 解决方案 > 如果存在于嵌套数组中,则创建或更新对象

问题描述

下面的代码很有效,因为它更新了嵌套数组中的对象。

但是,如果语言环境不存在,我正在努力寻找一种方法来推送新对象(例如{"locale" : "ar" , value:"مرحبا"}),或者如果语言环境已经存在则更新(例如){"locale" : "en" , value:"hello"}

更新代码:

    Project.findOneAndUpdate(
       {_id:projectId, 'sections._id': sectionId},
       { "$set": { "sections.$.subheader": {"locale":args.lang,"value":args.title} }},
       { upsert : true, new: true, useFindAndModify: false },
       (err, section) => {

       }
    )

对象结构:

  "project": {
      "name": "project name",
      "sections": [
        { 
          "subheader": [{

           'locale' : "en",
            'value' :  "Helle"
                      },
          {
           'locale' : "fr",
            'value' :  "salut"
                      }]

        }
      ]
    }

标签: javascriptmongodbmongoose

解决方案


不幸的是,这不可能一次性完成。该upsert选项仅适用于集合中的对象,不适用于嵌套对象。

您可以通过首先尝试更新数组中的元素来解决此问题,然后检查嵌套数组中的对象是否匹配。如果没有匹配项,您可以使用 . 将其插入到嵌套数组中$addToSet

此外,您需要使用位置运算符来匹配嵌套数组:

Project.findOneAndUpdate(
    // match item in subheader array
    { _id: projectId, 'sections._id': sectionId, 'sections.subheader.locale': args.lang },
    // update existing item in subheader array
    { "$set": { "sections.$[section].subheader.$[subheader].value": args.title } },
    // we use arrayFilters here, don't use upsert now
    { arrayFilters: [{ 'section._id': sectionId }, { 'subheader.locale': args.lang }], useFindAndModify: false },
    (err, section) => {
        // check if section was found
        if (!section) {
            // add new object to array if it wasn't found yet
            Project.findOneAndUpdate(
                // match section
                { _id: projectId, 'sections._id': sectionId},
                // add new object to array
                { "$addToSet": { "sections.$.subheader": {"locale": args.lang,"value": args.title } }},
                (err, section) => {
                    console.log('created new locale')
                }
            )
        } else {
            console.log('updated existing locale')
        }
    }
)

推荐阅读