1

I have a collection with 80 documents, each document looks like the one below. Is there a way that I can search through each document's "data" array and find any objects that have a "color" of 'red', all in one query to the mongodb database? or would I have to make 80 different queries to the mongodb database to do this?

{
  _id: 'j3k1jrh123h42',
  data: [
    {name: 'ben', color: 'red'},
    {name: 'tom', color: 'blue'},
    {name: 'will', color: 'red'},
    {name: 'jack', color: 'red'},
    {name: 'bob', color: 'yellow'}
  ],
  class: '8A',
  lastUpdate: '12-05-2021'
}
willmahon
  • 319
  • 4
  • 13
  • see similar question [How to filter array in subdocument with MongoDB](https://stackoverflow.com/questions/15117030/how-to-filter-array-in-subdocument-with-mongodb) – turivishal May 07 '21 at 14:21
  • I don't think that question is asking about querying multiple documents though – willmahon May 07 '21 at 14:45
  • your question is not clear, okay for multiple conditions you can use $elemMatch operator. – turivishal May 07 '21 at 15:00

3 Answers3

1

You can get records that have an element with color: red by

Model.find({"data.color": "red"})

If you want to filter the data array such that it only has elements with color: red

Model.aggregate([
{
    $match: {
        "data.color": "red"
    }
},
{
    $project: {
        data: {
            $filter: {
                input: "$data",
                as: "doc",
                cond: { $eq: ["$$doc.color", "red"] }
            }
        }
    }
}
])
  • Is there any way to get an array of just the {name: 'jack', color: 'red'} objects, as opposed to getting an array of documents that only contain the filtered data? – willmahon May 11 '21 at 12:59
  • You can use "$unwind", "$replaceRoot" for that. Add the following stages to the existing pipeline. `{ "$unwind": "$data" }, { "$replaceRoot": { "newRoot": "$data" } }` – Asma Mubeen May 15 '21 at 08:19
0

Depending on what you are trying to do you can use aggregtion with $project and $reduce, or with $unwind and $match

Joe
  • 25,000
  • 3
  • 22
  • 44
0

You can find easy all documents containing any elements with data.color: red via $match , but if you want the result to contain only the color: red element arrays you can use $filter or $unwind/$match

R2D2
  • 9,410
  • 2
  • 12
  • 28