5

I have array in a document, and I try to receive the last element of this array.

My code is:

Post.find({_id:postId},{'comments':{'$slice':-1}});

this gives me all the object but the comments array contains only the last element.

on the other hand,

Post.find({_id:postId},{'comments':1});

give me only the comments.

I dont find how to combine the two commands together. How it can be done?

{
 "users":[],
 "comments":["string1","string2","string3"],
 "lastValue":"Wow"
 "name":"jow"
 "_id": {
    "$oid": "5747d6bdecfae9d0560077cc"
   },
}

Thanks

3
  • 1
    Can you please post sample document from your collection? Commented May 27, 2016 at 5:42
  • What's your objective? From which array you are trying to retrieve last element? Commented May 27, 2016 at 5:52
  • "comments":["string1","string2","string3"], Commented May 27, 2016 at 5:53

4 Answers 4

6

You might want to use mongodb (version 3.2) aggregation $slice like that:

Post.aggregate([
  { 
    $match: { 
      '_id.$oid': postId 
    }
  },
  { 
    $project: {
      comments: {
        $slice: [ "$comments", -1 ] 
      }
    }
  }
]);

In earlier versions of mongodb:

Post.aggregate([
  { 
    $match: { 
      '_id.$oid': postId 
    }
  },
  { 
    $unwind: "$comments"
  },
  {
    $group : {
      _id: "$_id.$oid",
      comment: { $last: "$comments" }
    }
  }
]);
Sign up to request clarification or add additional context in comments.

4 Comments

This is almost works, I use the second, but their is problem with the _id it dont find the _id. if I remove the _id:postId, I receive the last of every element..
@Alon in your example you search { _id: postId }, but in the given example there is $oid. All you need is to specify valid collection identifier in the $group _id field and $match criteria. Updated the answer.
Your fix dont work, I found that use , _id:mongoose.Types.ObjectId(postId) works
@Alon oh, I couldn't know what you have in postId, makes sense too.
5

I hope this helps.

db.Post.find(
  { _id: postId },
  { comments: { $slice: -1 }, _id: 0, users: 0, lastValue: 0, name: 0 },
);

1 Comment

I hoped that their is something simplest, cause if I add things to the scheme I have to change this line also.
4

In case of Mongoose, slice can work this way also,

model.find({ 
    // condition
})
.select('fields')
.slice('array', -1) // <------ Here
.then((data) => {
    // handle
})
.catch();

Just wrote pseudo code, as it might help someone.

Comments

0
db.collection_name.find({'name':'how'},{'comments': {$slice: -1}})

Comments

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.