title: Mongoose populate subdocs with condition and update those
body: <p>I'm having a problem regarding updating my <code>UserModel</code> subdocument which is <code>(OfferModel)</code></p>
  
  <pre><code>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'
      }
    }
  });
  </code></pre>
  
  <p>So here's the situation
  I have a user who has 3 offers on 1 post but a total of 10 offers as a whole</p>
  
  <pre><code>Post A = 3 offers.
  Post B = 7 offers.
  </code></pre>
  
  <p>Then I accepted one offer on post A, so i query the database and make the "deal" property under "buyer" to be set to "ok", there's no problem with that. Now i need to set "rejected" to the other 2 offers on the Post A.
  There's a solution for this if i do the Javascript way:</p>
  
  <ol>
  <li>Get the Post Id</li>
  <li>Populate the offers under User model, use match operator to only get offers on the specific post &amp; that hasn't been confirmed (which is 2 offers)</li>
  <li>iterate through them and just assign <code>user.offers.buyer.deal = "rejected"</code></li>
  <li>Save()</li>
  </ol>
  
  <p>With this approach it's fine, but i want to do it in Mongoose way, i just want to know how can i do it in mongoose way?</p>
  
  <p>I've also checked the <code>.update()</code> operator, but I can't seem to make it work properly or it's not the thing that i need.</p>
  
  <p>Any inputs on how can I update those 2 offers using just only Mongoose operators?</p>
  
  <p>Thank you</p>
  
  <p>**Update</p>
  
  <pre><code>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'
      }
    });
  </code></pre>
  
  <p>Error <code>CastError : Cast to ObjectId failed for value "ok" at path "offers"</code></p>
  
  <p>***Update 2 Sample Docs
  ****Update 3 before and after</p>
  
  <pre><code>// 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"),
    }]
  </code></pre>