0

I want to select only the objects having 'Foo' as 'category', but the following query returns all categories instead.

db.collection.findOne( {"data.category:"Foo"} )

Result

{
  "data": [
    {
      "category": "Foo",
       "name" : "A"
    },
    {
      "category": "Bar",
      "name" : "A"
    },
    {
      "category": "Bar",
      "name" : "A"
    }
  ]
}
Community
  • 1
  • 1
coder9
  • 1,571
  • 1
  • 27
  • 52
  • This is covered by the answers to [MongoDB extract only the selected item in array](http://stackoverflow.com/questions/3985214/mongodb-extract-only-the-selected-item-in-array). TL;DR: use `$elemMatch` to extract a single matching element per document, or [Aggregation Framework](http://docs.mongodb.org/manual/applications/aggregation/) to extract multiple matching elements per document. – Stennie Mar 31 '13 at 10:17

1 Answers1

2

db.collection.findOne(...) returns a document based on a query document ({"data.category:"Foo"} ). Your query says just that: "return the first document found on disk whose data field value contains a sub-document whose category field value is 'Foo' (or data contains an array of sub-documents where at least one item has a category field whose value is 'Foo'

The query to return the array sub-document (or object as you call it) is:

db.collection.findOne( {"data.category:"Foo"} , {"data.category.$" : 1, _id : 0})

Ori Dar
  • 18,687
  • 5
  • 58
  • 72
  • Thanks for the reply. But this returns exactly one match. How to retrieve the rest? i.e: 'name' of each 'Bar' – coder9 Mar 31 '13 at 05:42
  • You have more than one. Missed that. I think `db.collection.findOne( {"data.category:"Foo"} , {"data.category.$" : 1, _id : 0}, {multi : 1})` would work. if not, you should use MapReduce – Ori Dar Mar 31 '13 at 07:57
  • @orid: there is no such "multi" flag for find. There is a feature suggestion to return multiple results using an `$elemMatch` production or variation. See [SERVER-6612](https://jira.mongodb.org/browse/SERVER-6612) in the MongoDB Jira tracker. – Stennie Mar 31 '13 at 10:15