0

how to get the specific message by _id. I have a database schema as shown below:

{
    "_id": ObjectID("5846eedaf0b51ed02ed846e2"),
    "name": "conversation name"
    "messages": [
        {
            "_id": ObjectID("584820a96866b6283361a4b9"),
            "content": "hello",
            "status": 0,
            "type": 0
        },
        {
            "_id": ObjectID("584820d56866b6283361a4ba"),
            "content": "voices/1481122005696.mp3",
            "status": 0,
            "type": 3
        }
    ]
}
Tang Chanrith
  • 1,219
  • 12
  • 8
  • Possible duplicate of [MongoDB query with elemMatch for nested array data](http://stackoverflow.com/questions/20525754/mongodb-query-with-elemmatch-for-nested-array-data) – Neo-coder Dec 07 '16 at 16:21

2 Answers2

1
db.collection.find({}, {
    'messages': {
        $elemMatch: {
            '_id': ObjectId("584820a96866b6283361a4b9")
        }
    }
})

This will match on all documents in your collection, and return the matching array subfield in the projection. See the link posted in Yogesh's comment.

dyouberg
  • 2,206
  • 1
  • 11
  • 21
1

Since you tagged mongoose, I put it like this, but the query syntax is valid because is part of mongoDB query syntax:

Conversation.findOne({
  "messages._id": "584820a96866b6283361a4b9"
}, function(err, document){
    if (err) {
        console.log(err) 
        return
    }
    var message = document.messages.id("584820a96866b6283361a4b9")
})

The finOne() method will return the full parent document with all the messages (subdocuments) and other properties. You then need to filter out the subdocument. Mongoose provides a way to do this easily with: document.messages.id("584820a96866b6283361a4b9") where document would be the data object passed to the find callback

See: Match a Field Without Specifying Array Index on https://docs.mongodb.com/v3.2/tutorial/query-documents/#query-on-arrays

ztrange
  • 305
  • 2
  • 9