如何对mongodb文档进行原子自定义更新?

时间:2017-12-07 17:52:45

标签: javascript mongodb transactions

我知道MongoDB可以使用findOneAndModify进行原子更新,但这只允许基本操作,如set或increment。

我需要的是应用自定义函数来转换我的文档:

const updateDoc = async (event) => {
  const oldState = await db.collection(collectionName).findOne({ name });
  const newState = customFunction(oldState, event);
  await db.collection(collectionName).replaceOne({ name }, newState);
}

系统将调用此函数,该系统不会等待已解决的承诺继续工作:可以有多个同步调用。

有没有办法重写updateDoc使其成为原子,所以当我们这样做时:

updateDoc(event1); // note the absence of await
updateDoc(event2);

我们可以确定存储的文档是customFunction(customFunction(initState, event1), event2)

由于

1 个答案:

答案 0 :(得分:1)

一个可能的解决方案是一个任务队列,它将一个接一个地更新:

class Scheduler {
  constructor(){
    this.running = false;
    this.queue = [];
  }

  add(el){
     this.queue.push(el);
     if(!this.running) this.run();
  }

  async run(){
    this.running = true;
    while(this.queue.length) await this.queue.shift();
    this.running = false;
 }
}

可以这样:

 const dbTasks = new Sheduler();

 const updateDoc = async (event) => dbTasks.add( _ => {
   const oldState = await db.collection(collectionName).findOne({ name });
   const newState = customFunction(oldState, event);
   await db.collection(collectionName).replaceOne({ name }, newState);
});

updateDoc(evt1);
updateDoc(evt2);