Агрегация MongoDB на массиве Json (JAVA)

У меня есть типичное веб-приложение, в котором я пытаюсь создать фасеты из коллекции mongodb. В настоящее время это делается с помощью платформы агрегации с использованием драйвера Java (v2.10.1). Фасеты генерируются правильно, за исключением документов, содержащих подмассивы, например, у меня есть следующие документы json:

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

Возвращаемый набор результатов:

название:

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

цвет:

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

виды топлива:

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

Агрегированный результат поля fueltypes содержит все поля массива.

Однако желаемый результат должен быть:

виды топлива:

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

и соответствующий java-код:

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);

person user2144625    schedule 07.03.2013    source источник


Ответы (1)


Группировка по массиву «типы топлива» дает вам количество вхождений массива как такового.

Чтобы подсчитать его элементы по отдельности, вам придется использовать оператор $unwind, например:

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

и включите это перед оператором $group. В качестве альтернативы вы можете вызвать $unwind только в том случае, если str имеет значение «fueltypes».

Для получения дополнительной информации о раскрутке см. http://docs.mongodb.org/manual/reference/aggregation/

person ronasta    schedule 01.04.2013