0

Here's the answer everyone: It can't be done.

I have a huge schema that I inherited. It has an array of objects and I am targeting an array of objects nested within that. Here is the schema

board: {
  "lists": [
    { "id": 12,     
      "cards": [
        { "id": 123,
          "cssClass": "default"
        },
        { "id": 124,
          "cssClass": "default"
        }
      ]
    },
    {
      "id": 13,
      "cards":[
      ]
    }
  ]
}

The cards.cssClass is what I'm trying to update. I have a statics that does a great job of getting the data for a particular card id:

BoardSchema.statics.findIndivdualCard = function(cardId, cb) {
  return this.aggregate([
    { "$match": { "id": 2826249 } },
    { "$unwind": "$lists" },
    { "$match": { "lists.cards.id": cardId } },
    { "$unwind": "$lists.cards" },
    { "$match": { "lists.cards.id": cardId } },
    { "$project": { "_id": 0, "lists": 1 } }
  ], cb)
}

So when I have a put route come up I'm calling the static and updating the cssClass:

exports.updateCard = (req, res, next) => {
  const boardId = parseInt(req.params.boardId);
  const cardId = parseInt(req.params.cardId);

  Board.findIndivdualCard(cardId, (err, list) => {
    let card = list[0].lists.cards;
    list[0].lists.cards.cssClass = req.body.cssClass;

    card.save((err) => {
      if (err)
        return next(err);

      res.json(card);
    });
  });
};

However I'm getting an error that says card.save is not a function. So I tried list (which is the callback) and got the same error.

I'm doing something stupid here, but not sure what. I hate the schema, but there is nothing I can do about it. Any help is appreciated.

This has gotten quite frustrating. This has been flagged as a duplicate, however there is no answer on the original duplicate.

Seriously, can this be done or not? Simple answer.

s.Lawrenz
  • 302
  • 3
  • 17
  • I would guess your problem is that you just get a projection back from your aggregation pipeline, so no actual model. You would probably want to create a new instance of your Board model, then assign the values you get from the projection and then save that thing. There may be easier ways, though. – dnickless Nov 10 '17 at 14:48
  • 1
    Stop editing your question and learn. The answer provided is clear. You CANNOT "atomically" update a "matched element" within a nested array as MongoDB presently does not allow it. Either A. Use "static" index notation for "known" element positions just like the answer says. B. CHANGE your schema, which is the recommended action and there is DETAIL explaining why. C. Sit on your hands and wait for MongoDB 3.6 where you can do this, but it still won't make querying nested arrays any easier. Sometimes when you ask a question here the answer actually is "You cannot do it that way". – Neil Lunn Nov 14 '17 at 20:39
  • Nothing about the duplicate answer was 'clear'. Thanks for telling me it can't be done. – s.Lawrenz Nov 14 '17 at 20:47

0 Answers0