猫鼬$推不断增加的两个条目

Phi*_*lip 8 database mongoose mongodb node.js mongoose-schema

这里是我userproduct架构:

const productSchema = new Schema({
  //... 
  addedBy: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "users"
  }
});

const userSchema = new Schema({   
  //...
  addedItems: [{
    type: mongoose.Schema.ObjectId,
    ref: "products"
  }]
});

mongoose.model("products", productSchema);
mongoose.model("users", userSchema);
Run Code Online (Sandbox Code Playgroud)

在我的节点后端路线我做这个查询:

User.findOneAndUpdate(
  { _id: req.body.id },
  { $push: { addedItems: newProduct._id } },
  { upsert: true, new: true },
  function(err, doc) {
    console.log(err, doc);
  }
);
Run Code Online (Sandbox Code Playgroud)

console.log打印出这样的:

{
    //...
    addedItems: [ 5ab0223118599214f4dd7803 ]
}
Run Code Online (Sandbox Code Playgroud)

一切看起来都不错。我实际上是使用前端网站来查看我的mongo数据库的数据;我使用mlab.com,这是什么节目:

{
//...
"addedItems": [
        {
            "$oid": "5ab0223118599214f4dd7803"
        },
        {
            "$oid": "5ab0223118599214f4dd7803"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

问:到底发生了什么?为什么它添加一个额外的进入addedItems?!虽然我的console.log仅表现之一。

注意:

我测试,看看后台路线是被称为不止一次。它不是。

这似乎是一个问题,$push因为如果我{ addedItems: newProduct._id }只有一个条目,那么它将覆盖整个数组。

编辑:

做了一个测试项目以产生相同的结果:https : //github.com/philliprognerud/test-mcve-stackoverflow

谁能弄清楚是怎么回事?

Joh*_*yHK 10

问题是由于您对诺言(通过异步/等待)和回调的混合使用导致的findOneAndUpdate,最终导致两次执行命令。

解决问题:

const updatedUser = await User.findOneAndUpdate(
  { id: userID },
  { $push: { addedItems: newProduct.id } },
  { upsert: true, new: true }
);

console.log(updatedUser);
Run Code Online (Sandbox Code Playgroud)

未来的读者会注意,await问题中的此处未显示,而是在MCVE中显示。