0

I am saving an updated array of _id's to an array on a document. If I check the document, everything is updating quite nicely, but when I populate right afterward using a new find query, it doesn't work right. populate wasn't working for me, so I decided to handle it manually and I am successful at filling them in, but they're in the wrong order.


export function sort_update(req, res) {

  Action.findOneAndUpdate({
    _id: req.query.action
  }, {
    child_actions: req.body.newArray
  }, {
    useFindAndModify: false, new: true
  }, function(err, doc) {
    if (err) return res.send(500, {
      error: err
    });

    console.log("child action id strings after update", doc.child_actions); // ["1", "2"] correct!

    Action.find({'_id': {$in: doc.child_actions }}, function(err, child_action_docs) {
      if (err) return res.send(500, {
        error: err
      });

      console.log("child action objects after fill", child_action_docs); // [{ _id: "2" }, { _id: "1" }] wrong!

      doc.child_actions = child_action_docs;
      res.send(doc);
    });

  });
}

Why are they in the wrong order? Does {'_id': {$in: doc.child_actions }} simply not guarantee any order at all? Do I have to re-sort my objects to the doc.child_actions order deliberately or is there a simpler way of telling mongodb to keep the order in the original array?

Gabriel Kunkel
  • 2,643
  • 5
  • 25
  • 47
  • It's always advisable to apply sort by if you are expecting something in the correct order. You might receive a different order if you don't apply for order. – RICKY KUMAR Dec 01 '19 at 07:03
  • 1
    The retrieval order is not maintained by the `$in` operator, and an option to do so is as suggested, sort them with a key in the same query. More info on this: [Does MongoDB's $in clause guarantee order](https://stackoverflow.com/questions/22797768/does-mongodbs-in-clause-guarantee-order) and [here](https://stackoverflow.com/questions/3142260/order-of-responses-to-mongodb-in-query) – ambianBeing Dec 01 '19 at 12:20
  • @ambianBeing this makes sense. Thanks so much. I ended up just throwing a sort afterwards: `child_action_docs.sort((a, b) => doc.child_actions.indexOf(a) > doc.child_actions.indexOf(b) ? 1 : -1 )` – Gabriel Kunkel Dec 01 '19 at 13:59
  • 1
    @ambianBeing will approve answer if you wanted to put that as an answer. – Gabriel Kunkel Dec 01 '19 at 13:59
  • @GabrielKunkel Would suggest you yourself post the answer and accept to help future readers. Since you almost figured it out in the question itself +1. – ambianBeing Dec 01 '19 at 14:02

0 Answers0