2

Update: Problem here was that the native MongoDB driver needed the objectID in a different format than Mongoose. Instead of {_id: story_id} I needed to do, {_id: new mongoose.Types.ObjectId(story_id)}. The reason it returned just the two fields was that it was creating a new document with {_id: story_id} rather than updating the document which was {_id: {$oid: story_id}}. However, my original reason for doing this with the native driver vs. mongoose turned out to not work. Even the native driver does not accept positive $slice values. So I'm still looking for a way to insert an object to the beginning of an array using Mongoose or the native driver accessed through Mongoose (which does not support $position or positive $slice values).

When I run the query below, the returned results only include _id, messages and participants. I would like to get the full story record back rather than just the updated fields. Is there a way to do this? Based on Node MongoDB Native driver documentation (http://mongodb.github.io/node-mongodb-native/api-generated/collection.html#findandmodify) the "fields" parameter from the mongo console is not implemented in the findAndModify driver. I want to avoid having to do a second query to get the just updated record.

Story.collection.findAndModify(
{"_id": story_id},
{"_id": "asc"},
{ 
    "$push": {
"messages": {
  "$each": [message],
  "$sort": { "_id": -1},
  "$slice": 500 
    },
  },
    "$addToSet": {"participants": user_id},
},
    {new: true},
    {fields: {"feeling":1, "description":1, "image_height":1, "image_width":1, "storyteller":1, "image_url":1, "participants":1}},   // -> this line is ignored by MongoDB native driver

      {upsert: true}

)
2
  • If you're using Mongoose, why aren't you calling Story.findByIdAndUpdate? Regardless, you should get the whole doc back, not just the updated fields. Commented Sep 21, 2014 at 13:28
  • Mongoose findByIdAndUpdate doesn't have support for adding to the beginning of array, as I am doing here with $sort and $slice (Mongoose looks for negative $slice values and returns an error. This query as shown here does not return the whole doc back. Commented Sep 21, 2014 at 22:58

1 Answer 1

3

You can insert elements at the beginning of an array field with a $push that uses the $each and $position modifiers (which is supported by Mongoose):

Story.findByIdAndUpdate(story_id, {
    $push: {
      messages: {
        $each: [message],
        $position: 0
      },
    },
    $addToSet: {participants: user_id},
  }, {
    new: true,
    upsert: true
  },
  function (err, newDoc) { ... }
);
Sign up to request clarification or add additional context in comments.

6 Comments

Mongoose does not support passing through of the $position parameter. See: github.com/LearnBoost/mongoose/issues/2024 and last reply here" stackoverflow.com/questions/23083041/… The error from mongoose is that $each can only be paired with $sort or $slice
@PraneethWanigasekera That bug is marked as fixed in 3.8.12 and it worked fine when I tested it with Mongoose 3.8.16.
it would be awesome if it worked. I am using 3.8.16 too. Here's the error I get with the above code: { [OperationalError: exception: $each term takes only $slice (and optionally $sort) as complements] name: 'OperationalError', message: 'exception: $each term takes only $slice (and optionally $sort) as complements', cause: { [MongoError: exception: $each term takes only $slice (and optionally $sort) as complements] Thanks so much for your help.
@PraneethWanigasekera $position support was added in MongoDB 2.6. What server version are you running?
Yes, you're right. I think that's what's going on. My Mongolab db version which I don't have control over is 2.4.5 I believe.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.