Filter on findOne

This might be the silliest questions of all, but I can’t get it to work…

I am testing with the following to get the “name”:“goodBanana” object . I have tried a few filter options but looks like I am missing something fundamental…

{
  "banana": [
    {
      "name": "goodBanana",
      "ripe": true
    },
    {
      "name": "badBanana",
"ripe": false
    }
  ]
}
 findOne({"banana.name":"goodBanana"})

returns the entire document... 
{
  _id: ObjectId("6504850c64b81fce975f7e1e"),
  banana: [
    {
      name: 'goodBanana',
      ripe: true
    },
    {
      name: 'badBanana',
      ripe: false
    }
  ]
}

All I wanted is

 {
      name: 'goodBanana',
      ripe: true
 }

Tried this with $elemMatch as well and same result.

Any help is much appreciated.

So when you do a findOne, it returns the entire document, to get an element from an array you need to do the $unwind aggregation state. I added the document and did the aggregation with a match and limit to 1. Then it unwinds it into two documents, then matches those two documents for ‘goodBanana’

[
  {
    $match:
      /**
       * query: The query in MQL.
       */
      {
        "banana.name": "goodBanana",
      },
  },
  {
    $limit:
      /**
       * Provide the number of documents to limit.
       */
      1,
  },
  {
    $unwind:
      /**
       * path: Path to the array field.
       * includeArrayIndex: Optional name for index.
       * preserveNullAndEmptyArrays: Optional
       *   toggle to unwind null and empty values.
       */
      {
        path: "$banana",
      },
  },
  {
    $match:
      /**
       * query: The query in MQL.
       */
      {
        "banana.name": "goodBanana",
      },
  },
]

Output:

{
  "_id": {
    "$oid": "65049795bbe0655ee98b3808"
  },
  "banana": {
    "name": "goodBanana",
    "ripe": true
  }
}

Aggregation stages in Atlas




You can add a $project to remove the _id

thank you so much @tapiocaPENGUIN for taking the time to show how to achieve my goal. You have thought me few things there for future…

  • using unwind
  • the solution steps and the underlaying solution design with reasoning
  • how to use the “aggregation” window in Atlas!

Legend!

Alternatives that are good to know:

Rather than $unwind and $match you may $filter the array in a $project.

You may also use $elemMatch in a projection in your findOne.

Thanks @steevej .

I found out about using $filtering the array in a $project. Good that you mentioned…

By the way, just started using MongoDB, so I am a newbie…

Tried $elemMatch for few hours today. it only returns the first array item that matches the condition. This is the problem… If you were to add to more bananas with the same values, $elemMatch still returns a single item. Do you know a way to do it with $elemMatch?

This is the documented behaviour:

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.