2016-07-05 5 views
1

Я пытаюсь выполнить операцию агрегации, используя Java, используя mongo-java-драйвер. Я провел некоторые другие операции поиска, но я не могу сделать следующую агрегацию правильно в Java:Mongo aggregation in java: группа с несколькими полями

db.I1.aggregate([ 
    { "$match": { "ci": 862222} }, 
    { "$match": { "gi": { "$ne": null } }}, 
    { "$group": { 
     "_id": { 
      "ci": "$ci", 
      "gi": "$gi", 
      "gn": "$gn", 
      "si": "$si" 
     } 
    }}, 
    { "$group": { 
     "_id": { 
      "ci": "$_id.ci", 
      "gi": "$_id.gi", 
      "gn": "$_id.gn" 
     }, 
     "sn": { "$sum": 1 } 
    }}, 
    { "$sort" : { "_id.gi" : 1}} 
]) 

Я попробовал несколько способов и методы для выполнения этой агрегации в Java, но я не могу для правильного ввода полей группы "ci", "gi", "gn","si" в методе coll.aggregate(asList()). То, что я получил до сих пор, заключается в следующем:

MongoCollection<Document> coll = mongo.getCollection("I1"); 

Document matchCourse = new Document("$match", 
    new Document("ci", Integer.parseInt(courseid))); 

Document matchGroupNotNull = new Document("$match", 
    new Document("gi", new Document("$ne", null))); 

List<Object> list1 = new BasicDBList(); 
    list1.add(new BasicDBObject("ci", "$ci")); 
    list1.add(new BasicDBObject("gi", "$gi")); 
    list1.add(new BasicDBObject("gn", "$gn")); 
    list1.add(new BasicDBObject("si", "$si")); 

Document group1 = new Document(
    "_id", list1).append("count", new Document("$sum", 1)); 

List<Object> list2 = new BasicDBList(); 
list2.add(new BasicDBObject("ci", "$_id.ci")); 
list2.add(new BasicDBObject("gi", "$_id.gi")); 
list2.add(new BasicDBObject("gn", "$_id.gn")); 

Document group2 = new Document(
    "_id", list2).append("sn", new Document("$sum", 1)); 

Document sort = new Document("$sort", 
    new Document("_id.gi", 1)); 

AggregateIterable<Document> iterable = coll.aggregate(asList(matchCourse, 
    matchGroupNotNull, group1, group2, sort)); 

Я знаю, что это не правильно, но я включил его, чтобы дать вам представление о том, что я делаю. Я искал это по-разному и читал несколько страниц, но я не нашел решения. Имеющаяся документация для MongoDB-Java (1, 2) слишком короткая для меня и не включает этот случай.

Как выполнить этот запрос в Java? Любая помощь будет оценена по достоинству.

спасибо!

ответ

5

Наконец-то я пришел к решению. Были некоторые ошибки в вопросе, что я в курсе, как это была последняя попытка после достижения некоторой точки отчаяния, но в конце концов, вот окончательное решение:

MongoDatabase mongo = // initialize your connection; 
Document matches = new Document("$match", 
    new Document("gi", new Document("$ne", null)) 
    .append("ci", Integer.parseInt(courseid))); 

Document firstGroup = new Document("$group", 
    new Document("_id", 
     new Document("ci", "$ci") 
     .append("gi", "$gi") 
     .append("gn", "$gn") 
     .append("si", "$si")) 
    .append("count", new Document("$sum", 1))); 

Document secondGroup = new Document("$group", 
    new Document("_id", 
     new Document("ci", "$_id.ci") 
     .append("gi", "$_id.gi") 
     .append("gn", "$_id.gn")) 
    .append("ns", new Document("$sum", 1))); 

Document sort = new Document("$sort", 
    new Document("_id.gi", 1));    

List<Document> pipeline = Arrays.asList(matches, firstGroup, 
    secondGroup, sort); 
AggregateIterable<Document> cursor = mongo.getCollection("I1") 
    .aggregate(pipeline); 

for(Document doc : cursor) { // do stuff with doc } 

Вместо того, чтобы пытаться создать списки ключевых значений , Я просто добавил элементы к документам. Надеюсь, это будет полезно для кого-то!