Search code examples
node.jsmongodbsubdocument

Find documents with sub-documents matching both of two (or more) properties


In Node with Mongoose I want to find an object in the collection Content. It has a list of sub-documents called users which has the properties stream, user and added. I do this to get all documents with a certain user's _id property in there users.user field.

Content.find( { 'users.user': user._id } ).sort( { 'users.added': -1 } )

This seems to work (although I'm unsure if .sort is really working here. However, I want to match two fields, like this:

Content.find( { 'users.user': user._id, 'users.stream': stream } } ).sort( { 'users.added': -1 } )

That does not seem to work. What is the right way to do this?


Here is a sample document

{
    "_id" : ObjectId("551c6b37859e51fb9e9fde83"),
    "url" : "https://www.youtube.com/watch?v=f9v_XN7Wxh8",
    "title" : "Playing Games in 360°",
    "date" : "2015-03-10T00:19:53.000Z",
    "author" : "Econael",
    "description" : "Blinky is a proof of concept of enhanced peripheral vision in video games, showcasing different kinds of lens projections in Quake (a mod of Fisheye Quake, using the TyrQuake engine).\n\nDemo and additional info here:\nhttps://github.com/shaunlebron/blinky\n\nThanks to @shaunlebron for making this very interesting proof of concept!\n\nSubscribe: http://www.youtube.com/subscription_center?add_user=econaelgaming\nTwitter: https://twitter.com/EconaelGaming",
    "duration" : 442,
    "likes" : 516,
    "dislikes" : 13,
    "views" : 65568,
    "users" : [ 
        {
            "user" : "54f6688c55407c0300b883f2",
            "added" : 1427925815190,
            "_id" : ObjectId("551c6b37859e51fb9e9fde84"),
            "tags" : []
        }
    ],
    "images" : [ 
        {
            "hash" : "1ab544648d7dff6e15826cda7a170ddb",
            "thumb" : "...",
            "orig" : "..."
        }
    ],
    "tags" : [],
    "__v" : 0
}

Solution

  • Use $elemMatch operator to specify multiple criteria on an array of embedded documents:

    Content.find({"users": {$elemMatch: {"user": user.id, "stream": stream}}});