【问题标题】:Mongoose - update filtered reference id without race conditionMongoose - 在没有竞争条件的情况下更新过滤的参考 ID
【发布时间】:2021-02-14 19:55:39
【问题描述】:

例如,我有两个猫鼬模式,例如

UserSchema = new mongoose.Schema({
    name: {type: String},
    pet: {type: mongoose.Schema.Types.ObjectId, ref: 'Pet'}
})

Users = mongoose.model('User', UserSchema)
PetSchema = new mongoose.Schema({
    name: {type: String}
})
Pets = mongoose.model('Pet', UserSchema)

我想做类似的事情

UPDATE Users SET PET=(SELECT _id FROM Pets WHERE name=petname) where name=username

可以通过以下两个步骤来完成。

  1. 从 Pets 集合中找到 name=petname 的 _id。
  2. 从用户集合中更新 name=username 的宠物。

由于在第 1 步和第 2 步之间,可以删除宠物,所以我想使用单个 mongoose 查询。如何使用单个 Query 对象实现此目的?

【问题讨论】:

  • mongodb 只是在文档级别真正原子。宠物需要单独收藏吗?它们可以嵌入为sub document 吗? 4.2+ 的副本集现在可以有transactions,但我认为这对这种情况没有帮助。

标签: javascript node.js mongodb mongoose


【解决方案1】:

我知道的唯一允许这样做的查询是aggregate + forEach 的组合。例如:

Users.aggregate([
  {
    $lookup: {
      from: 'Pets',
      localField: 'petname',
      foreignField: 'name',
      as: 'pets'
    }
  }
]).forEach(function(doc) {
  Pets.updateOne({ _id: doc._id }, { $set: { name: doc.pets[0].petname } });
});

但只有当您的join 操作仅返回一个连接文档时,才会正确更新。如果UPDATE Users SET PET=(SELECT _id FROM Pets WHERE name=petname) where name=username 子查询只返回一个文档,那么这个解决方案应该适合你。

【讨论】:

    猜你喜欢
    • 2013-12-23
    • 1970-01-01
    • 2013-07-16
    • 2023-02-09
    • 2012-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-08
    相关资源
    最近更新 更多