简体   繁体   English

java中的Mongo聚合:具有多个字段的组

[英]Mongo aggregation in java: group with multiple fields

I'm trying to perform an aggregation operation using in Java using the mongo-java-driver.我正在尝试使用 mongo-java-driver 在 Java 中执行聚合操作。 I've performed some other find operations, but I'm unable to do the following aggregation correctly in Java:我已经执行了一些其他的查找操作,但我无法在 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}}
])

I've tried several ways and methods to perform that aggregation in Java, but I'm unable to include the group fields "ci", "gi", "gn","si" correctly in the coll.aggregate(asList()) method.我已经尝试了几种在 Java 中执行聚合的方法和方法,但是我无法在coll.aggregate(asList())正确包含组字段"ci", "gi", "gn","si" coll.aggregate(asList())方法。 What I got so far, is the following:到目前为止,我得到的是以下内容:

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

I know it's not correct, but I included it to give you an idea of what I am doing.我知道这是不正确的,但我包含它是为了让您了解我在做什么。 I've googled this in many different ways and read several pages, but I didn't find any solution.我用许多不同的方式在谷歌上搜索并阅读了几页,但我没有找到任何解决方案。 The available documentation for MongoDB-Java( 1 , 2 ) is too short for me and doesn't include this case. MongoDB-Java( 1 , 2 ) 的可用文档对我来说太短了,不包括这种情况。

How can I perform that query in Java?如何在 Java 中执行该查询? Any help would be appreciated.任何帮助将不胜感激。

Thank you very much!!非常感谢!!

Finally I've come to a solution.最后我找到了解决方案。 There were some errors in the question that I posted, as it was the last attempt after reaching some point of desperation, but finally, here is the final solution:我发布的问题中有一些错误,因为这是达到某种绝望程度后的最后一次尝试,但最后,这是最终解决方案:

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 }

Instead of trying to create lists of key-values, I just appended the elements to the documents.我没有尝试创建键值列表,而是将元素附加到文档中。 Hope it will be useful for somebody!!希望它对某人有用!!

This question is quite old but was the top match on google when I searched so if anyone is looking for a solution to this I managed to do it in the following way这个问题很老了,但是当我搜索时是谷歌上的最佳匹配,所以如果有人正在寻找解决方案,我设法通过以下方式做到这一点

Aggregation.group(Fields.fields()
            .and("field1")
            .and("field2"))
            .first("name")
            .`as`("name")
            .count().`as`("count")

This will produce the following MDB query:这将产生以下 MDB 查询:

   { "$group" : 
        { "_id" : 
        { "field1" : "$field1", "field2" : "$field2"}, 
        "name" : { "$first" : "$name"}, 
        "count" : { "$sum" : 1}
   }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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