1

I have the following data structure saved in a mongodb collectionn named images

[
    {
        folder: 'cats',
        files: [
            {filename: 'redCat.jpg', _id: 1},
            {filename: 'blueCat.jpg', _id: 2},
            {filename: 'yellowCat.jpg', _id: 3},
        ]
    },{
        folder: 'dogs',
        files: [
            {filename: 'redDog.jpg', _id: 4},
            {filename: 'blueDog.jpg', _id: 5},
            {filename: 'yellowDog.jpg', _id: 6},
        ]
    },{
       ...
    }
]

I need to extract the id of a particular image, given the folder and the filename. I'm able to get all the images in a particular folder

db.images.find({folder:"cats"}, {files:1})

but I don't know how to filter out the files array in the same query, in order to get the blueCat.jpg image id. If possible I'd avoid two sequential queries.

I tried the following query

db.images.find({folder:"cats", "files.filename":"blueCat.jpg"})

but what I get is, again, the whole file list in the cats folder. What I'm triyng to get is something like:

{filename: 'blueCat.jpg', _id: 2}

Any hint? Thanks in advance

2

2 Answers 2

2

Try this-

db.images.find({"folder":"cats","files.filename":"blueCat.jpg"}, {'files.$":1})

give you-

{ "_id" : ObjectId("576a92b47f0d626b7a74c325"), "files" : { "filename" : "blueCat.jpg", "_id" : 2 } }

And if you want to fetch complete list-

db.images.find({"folder":"cats","files.filename":"blueCat.jpg"}, {'files":1})

will result you-

{ "_id" : ObjectId("576a92b47f0d626b7a74c325"),
 "files" :
 { "filename" : "blueCat.jpg", "_id" : 2 }
 {"filename" : "xxxCat.jpg", "_id" : N }
 {"filename" : "yyyCat.jpg", "_id" : N }
 }
Sign up to request clarification or add additional context in comments.

Comments

0

You can do this using the aggregation pipeline, and unwinding the files array, then query (match) the filename you are looking for.

For example:

db.images.aggregate([{$unwind:"$files"},{$match:{"files.filename":"blueCat.jpg"}}])

will give you:

{ "_id" : ObjectId("576a92b47f0d626b7a74c325"), "folder" : "cats", "files" : { "filename" : "blueCat.jpg", "_id" : 2 } }

You can further refine the output document by using project. Eg:

db.images.aggregate([{$unwind:"$files"},{$match:{"files.filename":"blueCat.jpg"}},{$project:{"files.filename":1, "files._id":1}}])

will return:

{ "_id" : ObjectId("576a92b47f0d626b7a74c325"), "files" : { "filename" : "blueCat.jpg", "_id" : 2 } }

2 Comments

What if both cats and dogs folder contain an image with the same name?
You would get two documents returned.

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.