Mongoose:通过 findOneAndUpdate 查询使用对象数组的总和更新根数据属性不起作用

Posted

技术标签:

【中文标题】Mongoose:通过 findOneAndUpdate 查询使用对象数组的总和更新根数据属性不起作用【英文标题】:Mongoose: Updation of root data attribute with sum of object array through findOneAndUpdate query not working 【发布时间】:2021-01-31 15:47:34 【问题描述】:

我正在尝试使用 Node mongoose 库更新 mongo 集合中的一个数组元素。这是我的 mongo 架构的样子:


    "_id": ObjectId("5f8a94ccc8452643f1498419"),
    "private": false,
    "score": 2000,
    "questions": [
        "_id": ObjectId("5f8a94e8c8452643f149841c"),
        "order": 1,
        "category": "TEXT",
        "definition": "about us",
        "score": 1,
    , 
        "_id": ObjectId("5f8a94e8c8452643f149841d"),
        "order": 2,
        "category": "html",
        "definition": "about us",
        "score": 0.5
    ]

我正在更新问题数组中的分数,要更新的根数组的分数属性是数组分数的总和,即

root score => question array1.score + array2.score

我使用了下面的猫鼬函数:

  Model.findOneAndUpdate(
    
      _id: id,
      "questions._id": qid,
    ,
    
     '$set': 
          'questions.$.order': 1,
          'questions.$.score': 1,
          'questions.$.type': 'HTML',
          '$sum':  'score': 'questions.score' 
      
    )

虽然所有其他属性都在更新,根分数永远不会更新

注意:$setoninsert 不是一个选项,因为在这种情况下,upsert 总是 false .

这是否有可能使用一个单个查询来执行这两个更新?

【问题讨论】:

【参考方案1】:

您可以从 MongoDB 4.2 开始使用update with aggregation pipeline,

$set 更新 id 与 qid 匹配的匹配问题 $setquestions 数组的分数更新根分数
let id = mongoose.Types.ObjectId("5f8a94ccc8452643f1498419");
let qid = mongoose.Types.ObjectId("5f8a94e8c8452643f149841c");
let question = 
  score: 1,
  order: 1,
  category: "TEXT"
;

Model.findOneAndUpdate(
   _id: id ,
  [
    $set: 
      questions: 
        $map: 
          input: "$questions",
          in: 
            $mergeObjects: [
              "$$this",
              
                $cond: [
                   $eq: ["$$this._id", qid] ,
                  question, // add update fields in object
                  
                ]
              
            ]
          
        
      
    
  ,
  
    $set: 
      score: 
        $reduce: 
          input: "$questions",
          initialValue: 0,
          in:  $add: ["$$value", "$$this.score"] 
        
      
    
  ]
)

Playground

【讨论】:

它有效。非常感谢老兄......你让我很开心:)

以上是关于Mongoose:通过 findOneAndUpdate 查询使用对象数组的总和更新根数据属性不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Mongoose:findOneAndUpdate 不返回更新的文档

Mongoose:findOneAndUpdate 不返回更新的文档

Mongoose:findOneAndUpdate 不返回更新的文档

Mongoose - 使用 findOneAndUpdate 更新子文档

Mongoose `findOneAndUpdate` 回调不传递更新的文档

Mongoose `findOneAndUpdate` 回调不传递更新的文档