Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB distinct aggregation

I'm working on a query to find cities with most zips for each state:

db.zips.distinct("state", db.zips.aggregate([      { $group:       { _id: {            state: "$state",             city: "$city"           },         numberOfzipcodes: {             $sum: 1          }       }     },      { $sort: {         numberOfzipcodes: -1          }       }   ]) ) 

The aggregate part of the query seems to work fine, but when I add the distinct I get an empty result.

Is this because I have state in the id? Can I do something like distinct("_id.state ?

like image 294
Lemonio Avatar asked May 03 '13 22:05

Lemonio


People also ask

How do I use distinct aggregation in MongoDB?

You can use $addToSet with the aggregation framework to count distinct objects. Not a generic solution, if you have a large number of unique zip codes per result, this array would be very large. The question was to get the city with MOST zip codes for each state, not to get the actual zip codes.

How do I get distinct documents in MongoDB?

To get distinct values, use distinct() in MongoDB. It finds the distinct values for a specified field across a single collection or view and returns the results in an array.

What does distinct do in MongoDB?

In MongoDB, the distinct() method finds the distinct values for a given field across a single collection and returns the results in an array. It takes three parameters first one is the field for which to return distinct values and the others are optional.

How do you use distinct aggregate?

If you use SELECT DISTINCT , then the result set will have no duplicate rows. If you use SELECT COUNT(DISTINCT) , then the count will only count distinct values. If you are thinking of using SUM(DISTINCT) (or DISTINCT with any other aggregation function) be warned.


2 Answers

You can use $addToSet with the aggregation framework to count distinct objects.

For example:

db.collectionName.aggregate([{     $group: {_id: null, uniqueValues: {$addToSet: "$fieldName"}} }]) 

Or extended to get your unique values into a proper list rather than a sub-document inside a null _id record:

db.collectionName.aggregate([     { $group: {_id: null, myFieldName: {$addToSet: "$myFieldName"}}},     { $unwind: "$myFieldName" },     { $project: { _id: 0 }}, ]) 
like image 103
dam1 Avatar answered Oct 21 '22 08:10

dam1


Distinct and the aggregation framework are not inter-operable.

Instead you just want:

db.zips.aggregate([      {$group:{_id:{city:'$city', state:'$state'}, numberOfzipcodes:{$sum:1}}},      {$sort:{numberOfzipcodes:-1}},     {$group:{_id:'$_id.state', city:{$first:'$_id.city'},                numberOfzipcode:{$first:'$numberOfzipcodes'}}} ]); 
like image 33
Sammaye Avatar answered Oct 21 '22 10:10

Sammaye