【问题标题】:Push to a nested array or push to array based on the item id - MongoDb node.js推送到嵌套数组或根据项目 id 推送到数组 - MongoDb node.js
【发布时间】:2022-01-17 06:43:37
【问题描述】:

我有这个架构:

...
recommended:{
    type:[{
        movieId:String,
        recommendedBy:[String]
    }],
    default:[],
},
name: {
    type: String,
}

从请求中我得到movieIdid。 如果已经没有其他具有相同movieId 的项目,我想向recommended 数组添加一个新对象,并在这两种情况下将id 添加到recommendedBy 嵌套数组中。

到目前为止我有这个:

        const user = User.findByIdAndUpdate({_id:'123'},
            {$AddToSet:{'recommended.$[movie].recommendedBy':id}},
            {arrayFilters:[{'movie.movieId':movieId}]})

这只会将已存在项目的recommendedBy 设置为具有相同movieId, 但不会使用新的movieId 属性推送新对象。 (所以这两个数组基本上都是 $AddToSet ) 我怎么能做到这一点?谢谢!

【问题讨论】:

    标签: javascript node.js arrays mongodb mongoose


    【解决方案1】:

    也许你需要像这样简单的东西来为推荐的数组元素做 upsert 或更新:

     db.collection.update({},
      [
       {
        $set: {
         recommended: {
          "$reduce": {
            "input": "$recommended",
            "initialValue": // assign your edit data as init value
            [
            {
              "movieId": "1",
              "recommendedBy": "who recommended"
            }
          ],
          "in": {
            "$cond": {
              "if": {
                $in: [
                  "$$this.movieId",
                  "$$value.movieId"
                ]
              },
              "then": "$$value",
              "else": {
                "$concatArrays": [
                  "$$value",
                  [
                    "$$this"
                  ]
                ]
                 }
                 }
                 }
                }
              }
            }
          }
        ])
    

    解释:

    1. 没有过滤器,但您可以在初始文档过滤器中添加任何内容以仅搜索有限的文档集。
    2. 在更新阶段,您使用 $reduce 检查输入数组元素,您需要更新插入或更新受影响数组元素中的值。

    (确认可以在 mongod 4.4 中工作)

    playground

    【讨论】:

    • 嘿!感谢您的时间,但是这并不能解决问题,因为如果您假设数组中已经有一个名为 test 的movieId,那么这个 quary 将向数组中添加另一个具有相同电影 ID 的项目,这就是我想要的避免。
    • 相应地调整了答案...
    • 这里是原始的和更多的想法:stackoverflow.com/questions/69747575/…
    • 哇这看起来真的很复杂,我没想到会这么难!
    【解决方案2】:

    我无法理解@R2D2 的回答,所以我想出了这个解决方法,它对我来说出乎意料地好,因为我还需要能够删除movieId 和所有recommendedBy

    我将架构更改为:

        recommanded:{
          type: Map,
          of:[String],
          default:{}
        },
    

    我正在删除/添加:

    User.findByIdAndUpdate({_id:"123",{$addToSet:{[`recommended.${movieId}`]:id}})
    

    User.findByIdAndUpdate({_id:"123",{$unset:{[`recommended.${movieId}`]:""}})
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-28
      • 1970-01-01
      • 1970-01-01
      • 2020-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多