Mongoose用条件填充subdocs并更新它们

时间:2018-05-19 05:28:43

标签: node.js mongodb mongoose

我在更新UserModel子文档时出现问题(OfferModel)

const user = Schema({
  name: String,
  offers: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Offer'
  }]
});

const offer = Schema({
  title: String,
  post: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Post'
  },
  buyer: {
    deal: String,
    user: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'User'
    }
  },
  seller: {
    deal: String,
    user: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'User'
    }
  }
});

所以这就是情况 我有一个用户在1个帖子上有3个优惠,但总共有10个优惠

Post A = 3 offers.
Post B = 7 offers.

然后我在帖子A上接受了一个提议,所以我查询数据库并将“买方”下的“交易”属性设置为“确定”,这没有问题。现在我需要将“拒绝”设置为帖子A上的其他2个优惠。 如果我使用Javascript方式,有一个解决方案:

  1. 获取帖子ID
  2. 在用户模型下填充优惠,使用匹配运算符仅获取特定帖子和优惠的优惠。尚未确认(这是2个优惠)
  3. 遍历它们并只分配user.offers.buyer.deal = "rejected"
  4. 保存()
  5. 用这种方法很好,但我想用Mongoose方式做,我只是想知道我怎么能以猫鼬的方式做到这一点?

    我还检查了.update()运算符,但我似乎无法使其正常工作,或者这不是我需要的东西。

    关于如何仅使用Mongoose运算符来更新这两个优惠的任何输入?

    谢谢

    **更新

    const user = await this.userRepo.findUser(req.user._id)
      .select('offers')
      .populate({
        path: 'offers',
        match: {
          post: req.body.postId,
          'buyer.feedback': 'none'
        }
      })
      .update({}, {
        '$set': {
          'offers.$.buyer.feedback': 'ok'
        }
      });
    

    错误CastError : Cast to ObjectId failed for value "ok" at path "offers"

    ***更新2个示例文档 ****在

    之前和之后更新3
    // John
    {
      "_id": ObjectId("5abf3c2fb9709a31244ee2a8"),
      "name": "john",
      "offers": [
        ObjectId("5ad2aac1b0ef21131439223c"), // Offer that i accepted
        ObjectId("5ad2ab39b0ef21131439223d"), // Offer i should reject
        ObjectId("5ad2b9b2751c39321c4173e4"), // Offer i should reject
        ObjectId("5ad2d0846778d91eb0b109a8"),
        ObjectId("5ad2d136e50e903240cdb4b9"),
        ObjectId("5ad2d14ae50e903240cdb4ba"),
        ObjectId("5ad2d2acde95b51e205b26fc"),
        ObjectId("5ad9cbaec9c10314148adcd8"),
        ObjectId("5ad9ccf60c7f492940d4bd9d"),
        ObjectId("5ad9cd2e0c7f492940d4bd9e"),
      ],
      "post": [
        ObjectId("5abf4eb433063a3ebc8ba78f"), // Post A
        ObjectId("5abf4ec533063a3ebc8ba790"),
      ]
    };
    
    // Offer that i accepted
    {
      "_id" : ObjectId("5ad2aac1b0ef21131439223c"),
        "buyer" : {
          "deal" : "ok",
          "feedback" : "none",
          "user" : ObjectId("5abf3c2fb9709a31244ee2a8")
      },
      "seller" : {
        "deal" : "none",
        "feedback" : "none",
        "user" : ObjectId("5abf3c2fb9709a31244ee8bf")
      },
      "post" : ObjectId("5abf4eb433063a3ebc8ba78f"),
    }
    
    // (BEFORE) Offer that i should reject
    [{
      "_id" : ObjectId("5ad2ab39b0ef21131439223d"),
      "buyer" : {
        "deal" : "none",
        "feedback" : "none",
        "user" : ObjectId("5abf3c2fb9709a31244ee2a8")
      },
      "seller" : {
        "deal" : "none",
        "feedback" : "none",
        "user" : ObjectId("5abf3c2fb9709a31244ee8bd")
      },
      "post" : ObjectId("5abf4eb433063a3ebc8ba78f"),
    },
    {
      "_id": ObjectId("5ad2b9b2751c39321c4173e4"),
      "buyer": {
        "deal": "none",
        "feedback": "none",
        "user": ObjectId("5abf3c2fb9709a31244ee2a8")
        },
      "seller": {
        "deal": "none",
        "feedback": "none",
        "user": ObjectId("5abf3c2fb9709a31244ee8aa")
        },
      "post": ObjectId("5abf4eb433063a3ebc8ba78f"),
    }]
    
    // (AFTER)
    [{
      "_id": ObjectId("5ad2ab39b0ef21131439223d"),
      "buyer": {
        "deal": "rejected",
        "feedback": "none",
        "user": ObjectId("5abf3c2fb9709a31244ee2a8")
      },
      "seller": {
        "deal": "none",
        "feedback": "none",
        "user": ObjectId("5abf3c2fb9709a31244ee8bd")
      },
      "post": ObjectId("5abf4eb433063a3ebc8ba78f"),
    },
      {
        "_id": ObjectId("5ad2b9b2751c39321c4173e4"),
        "buyer": {
          "deal": "rejected",
          "feedback": "none",
          "user": ObjectId("5abf3c2fb9709a31244ee2a8")
        },
        "seller": {
          "deal": "none",
          "feedback": "none",
          "user": ObjectId("5abf3c2fb9709a31244ee8aa")
        },
        "post": ObjectId("5abf4eb433063a3ebc8ba78f"),
      }]
    

1 个答案:

答案 0 :(得分:1)

你应该尝试这样的事情

Offers.update({
  "buyer.feedback": "none",  
  post: req.body.postId      //query
}, {
  '$set': {
    'buyer.feedback': 'ok'    // update operation
  }
})