whyp
whyp

Reputation: 613

Mongoose - getting a single document per value for a given field

For a collection with 200k documents like the following:

{ 
  name: Mario,
  profession: plumber,
  level: 8,
},
{
  name: Luigi,
  profession: plumber,
  level: 5,
},
{
  name: Walter,
  profession: cook,
  level: 10,
},
{
  name: Jesse,
  profession: cook,
  level: 3,
}

What would be an efficient query to get only a single document per profession, with or without sorting by level?

Upvotes: 0

Views: 38

Answers (2)

richsilv
richsilv

Reputation: 8013

To expand on @felix answer, you can do this easily with a MongoDB group operation. For example, in the MongoDB shell:

db.yourCollection.aggregate([
  { $group: { _id: '$profession', doc: { $first: '$$ROOT' } } }
])

will give you results like:

{
  _id: 'plumber',
  doc: {
    name: 'Mario',
    profession: 'plumber',
    level: 8
  }
},
{
  _id: 'cook',
  doc: {
    ...
  }
},
...

If more fine-grained control is required, you can filter the results before or after the grouping with $match. Any MongoDB adaptor for Node should give you access to this method.

Upvotes: 1

KARTHIKEYAN.A
KARTHIKEYAN.A

Reputation: 20088

use the $group and aggregate() function to get your expected result

Query:

 db.getCollection('agg').aggregate([
      { $group: { _id: '$profession', doc: { $first: '$$ROOT' }, count: { $sum: 1 } } }
    ])

Output:

/* 1 */
{
    "_id" : "cook",
    "doc" : {
        "_id" : ObjectId("59157ace263af55a862b78dc"),
        "name" : "Walter",
        "profession" : "cook",
        "level" : 10.0
    },
    "count" : 2.0
}

/* 2 */
{
    "_id" : "plumber",
    "doc" : {
        "_id" : ObjectId("59157ace263af55a862b78da"),
        "name" : "Mario",
        "profession" : "plumber",
        "level" : 8.0
    },
    "count" : 2.0
}

Upvotes: 0

Related Questions