Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongo aggregation on array elements

I have a mongo document like

{ "_id" : 12, "location" : [ "Kannur","Hyderabad","Chennai","Bengaluru"] }
{ "_id" : 13, "location" : [ "Hyderabad","Chennai","Mysore","Ballary"] }

From this how can I get the location aggregation (distinct area count). some thing like

Hyderabad 2, 
Kannur 1, 
Chennai 2, 
Bengaluru 1, 
Mysore 1, 
Ballary 1
like image 790
SURYA GOKARAJU Avatar asked Jan 03 '15 07:01

SURYA GOKARAJU


People also ask

How do I match an array element in MongoDB?

The $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria. If you specify only a single <query> condition in the $elemMatch expression, and are not using the $not or $ne operators inside of $elemMatch , $elemMatch can be omitted.

What is array aggregation?

The ARRAY_AGG function aggregates a set of elements into an array. Invocation of the ARRAY_AGG aggregate function is based on the result array type.

How do I filter an array in MongoDB?

Filter MongoDB Array Element Using $Filter Operator This operator uses three variables: input – This represents the array that we want to extract. cond – This represents the set of conditions that must be met. as – This optional field contains a name for the variable that represent each element of the input array.


1 Answers

Using aggregation you cannot get the exact output that you want. One of the limitations of aggregation pipeline is its inability to transform values to keys in the output document.

For example, Kannur is one of the values of the location field, in the input document. In your desired output structure it needs to be the key("kannur":1). This is not possible using aggregation. While, this can be used achieving map-reduce, you can however get a very closely related and useful structure using aggregation.

  • Unwind the location array.
  • Group by the location fields, get the count of individual locations using the $sum operator.
  • Group again all the documents once again to get a consolidated array of results.

Code:

db.collection.aggregate([
{$unwind:"$location"},
{$group:{"_id":"$location","count":{$sum:1}}},
{$group:{"_id":null,"location_details":{$push:{"location":"$_id",
                                               "count":"$count"}}}},
{$project:{"_id":0,"location_details":1}}
])

Sample o/p:

{
        "location_details" : [
                {
                        "location" : "Ballary",
                        "count" : 1
                },
                {
                        "location" : "Mysore",
                        "count" : 1
                },
                {
                        "location" : "Bengaluru",
                        "count" : 1
                },
                {
                        "location" : "Chennai",
                        "count" : 2
                },
                {
                        "location" : "Hyderabad",
                        "count" : 2
                },
                {
                        "location" : "Kannur",
                        "count" : 1
                }
        ]
}
like image 128
BatScream Avatar answered Oct 06 '22 04:10

BatScream