简体   繁体   中英

Mongodb Aggregation on Json Array (JAVA)

I have a typical web application in which I am trying to generate facets from the mongodb collection. This is currently being done using the aggregation framework using the Java driver (v2.10.1). The facets are generated correctly, except for the documents containing sub-arrays, for instance I have the following json documents:

  1. {name: polo, fueltypes:[benzin, lpg], color: black}
  2. {name: golf, fueltypes:[benzin, cng], color: blue}
  3. {name: a4, fueltypes:[diesel], color: blue}

The returned result set is:

name:

{_id: polo, count: 1}
{_id: golf, count: 1}
{_id: a4, count: 1}

color:

{_id: black, count: 1}
{_id: blue, count: 2}

fueltypes:

{_id: [benzin,lpg,cng,diesel], count: 3}

The aggregated result of the fueltypes field contains all the array fields.

However the desired result should be:

fueltypes:

{_id: benzin, count: 2}
{_id: lpg, count: 1}    
{_id: diesel, count: 1}    
{_id: cng, count: 1}    

and the corresponding java code:

String str = "name" ; //or fueltypes, color
// create match
BasicDBObject match = new BasicDBObject();
match.put("$match", new BasicDBObject());

// build the $projection operation
DBObject fields = new BasicDBObject();

// fields.put("count", 1);
DBObject project = new BasicDBObject();

// Now the $group operation
DBObject groupFields = new BasicDBObject();

DBObject unwindFields = new BasicDBObject();
// build the $projection operation
fields.put(str, 1);
project.put("$project", fields);

// Now the $group operation
groupFields.put("_id", "$" + str);

// performing sum and storing it in the count attribute
groupFields.put("count", new BasicDBObject("$sum", 1));

DBObject group = new BasicDBObject("$group", groupFields);
AggregationOutput output = serviceCollection.aggregate(match, project, group);

Grouping by the array "fueltypes" gives you the number of occurrences of the array as such.

To count it's elements individually, you'll have to use the $unwind operator, like so:

// create unwind
BasicDBObject unwind = new BasicDBObject();
unwind.put("$unwind", "$" + str);

and include this before the $group operator. Alternatively, you could call the $unwind only if str is "fueltypes".

For more information about unwind, see http://docs.mongodb.org/manual/reference/aggregation/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM