簡體   English   中英

如何在 mongoose 中更新數組中的嵌入文檔,其中操作應該是原子的,應該更新最新的文檔並返回更新的文檔?

[英]How to update embedded document in array in mongoose where operation should be atomic, should update on the latest one and return updated document?

目前正在使用 mongoose 開發 node.js 和 MongoDB。

//Document in mongoDB
{
  name: 'first',
  _id: '1000'
  phases: [{
      _id: 1,
      phaseName: 'phase1',
      stories: [{
          _id: s1,
          sname: 'sfirst'
        },
        {
          _id: s2,
          sname: 'ssecond'
        },
        {
          _id: s3,
          sname: 'sthird'
        }
      ],

    },
    {
      _id: 2,
      phaseName: 'phase2',
      stories: [{
          _id: s1,
          sname: 'sfirst'
        },
        {
          _id: s2,
          sname: 'ssecond'
        },
        {
          _id: s3,
          sname: 'sthird'
        }
      ],

    }
  ],
}

我所擁有的是

  1. id=1000(在mongodb中找到這個文檔)
  2. phaseId=1 和 remstoryId=s2(即從 id 為 1 的階段的故事中刪除 s2)
  3. phaseId=2, storyId={ _id: s4, sname: second}, position: 1 (在階段2中索引1處的故事中添加故事)

主要要求是這個操作應該是

  1. 原子
  2. 執行上述操作時,其他用戶無法對同一文檔進行操作。 我的意思是鎖定這個文件。

我可以使用 findOne() 和 save() 執行此操作嗎

Model.findOne({
  id
}, (err, plan) => {
  if (!err) {

    //REMOVE THE STORY FROM PHASE
    const phase = plan.phases.find((phase) => phase._id === delPhaseID);
    phase.stories = phase.stories.filter((story) => story._id !== delStoryId);

    //ADD STORY IN STORIES
    const addPhase = plan.phases.find((phase) => phase._id === addPhaseID);
    addPhase.stories.splice(pos, 0, story);

    //SAVE PLAN
    plan.save((err, doc) => {
       if(!err)
         console.log(doc) // UPDATED DOCUMENT
       });
  }
})

但是這個操作不是原子操作,如下圖來自masteringjs 我們如何解決這個問題

在此處輸入圖片說明

你可以嘗試findOneAndUpdate()arrayFilters

  • p1 id 的故事中移除的$pulls1
  • $pushp2特定位置使用$position
  • new: true返回更新的文檔
Model.findOneAndUpdate(
    { _id: "1000" },
    {
        $pull: {
            "phases.$[p1].stories": {
                _id: "s1"
            }
        },
        $push: {
            "phases.$[p2].stories": {
                $each: [{
                    _id: "s4",
                    sname: "fourth"
                }],
                $position: 1
            }
        }
    },
    {
        arrayFilters: [
            { "p1._id": 1 },
            { "p2._id": 2 }
        ],
        new: true
    }
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM