简体   繁体   English

将Java Spring代码从AggregationOutput更改为DBCollection Aggregation方法

[英]Change Java Spring code from AggregationOutput to DBCollection Aggregation methods

I'm updating a 2014 Java project with the latest libraries and MongoDB Java Driver changed from 3.0 to 3.6. 我正在使用最新的库更新2014 Java项目,并将MongoDB Java驱动程序从3.0更改为3.6。 Most of the codes has been updated but there is a specific query pretty complicated which is giving me problems. 大多数代码已更新,但是有一个非常复杂的特定查询,这给我带来了问题。

The Document is like this 该文件是这样的

{
    "_id" : ObjectId("58750a67ae28bc28e0705b0f"),
    "info": "description",
    "parentId", "variable-id-here"
    "issues": [
        {"name": "a", "closed": true},
        {"name": "b", "closed": false},
        {"name": "c", "closed": true}
    ],
    "bugs": [
        {"name": "d", "closed": false},
        {"name": "e", "closed": false},
        {"name": "f", "closed": true}
    ],
    "errors": [
        {"name": "g", "closed": true},
        {"name": "h", "closed": true},
        {"name": "i", "closed": false}
    ]
}

(even if elements in arrays are similar, they can't be grouped in a single array in the document with an extra "type" key with values [issues, bugs, errors], but that's not the point) (即使数组中的元素相似,也不能使用带有值[问题,错误,错误]的额外“类型”键将它们组合在文档中的单个数组中,但这不是重点)

The old script is this one 旧的脚本是这个

List<DBObject> aggregators = new ArrayList<>();
DBObject match = new BasicDBObject("$match", new BasicDBObject("parentId", myId));
DBObject project = new BasicDBObject();
List<String> domains = Arrays.asList("issues", "bugs", "errors");

for (Iterator<String> d = domains.iterator(); d.hasNext();) {
    String domain = d.next();
    //Reset values
    aggregators = new ArrayList<>();
    // Define MongoDB "$project" to find 'true' values on 'closed' flags
    project = new BasicDBObject("$project", new BasicDBObject("closedProblems", 
        new BasicDBObject("$filter",
            new BasicDBObject("input", "$"+domain)
                .append("as", "myObject")
                .append("cond", new BasicDBObject("$eq",
                    Arrays.<Object> asList("$$myObject.closed", true)
                )
            )
        )
    ));

    aggregators.add(match);
    aggregators.add(project);
    //db defined before. AggregationOutput is deprecated so must be changed
    AggregationOutput output = db.getCollection("myColl").aggregate(aggregators);

    // Now I can iterate results
    for (DBObject result : output.results()) {
        // ...
    }
}

I tried to use projects, expressions, etc. but I can't find a way to duplicate the MongoDB project with new Aggregation methods. 我尝试使用项目,表达式等,但是找不到用新的Aggregation方法复制MongoDB项目的方法。

The final result should use mongoTemplate . 最终结果应使用mongoTemplate anyMethods to execute the Aggregation in order to join new project guidelines anyMethods执行聚合以加入新的项目准则

Use below code in 3.6 driver. 在3.6驱动程序中使用以下代码。

DBCursor output = (DBCursor) db.getCollection("myColl").aggregate(aggregators, AggregationOptions.builder().build());
for (Iterator<DBObject> r = output.iterator(); output.hasNext();) {
      DBObject result = r.next();
      ...
}

Update: 更新:

import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
import static org.springframework.data.mongodb.core.aggregation.ArrayOperators.Filter.filter;
import static org.springframework.data.mongodb.core.aggregation.ComparisonOperators.Eq.valueOf;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.aggregation.*;

List<AggregationOperation> aggregators;
MatchOperation match = Aggregation.match(Criteria.where("parentId").is(myId));
List<String> domains = Arrays.asList("issues", "bugs", "errors");
for (Iterator<String> d = domains.iterator(); d.hasNext();) {
     String domain = d.next();
     aggregators = new ArrayList<>();
     ProjectionOperation project = project().and(filter(domain)
                        .as("myObject")
                        .by(valueOf(
                                "myObject.closed")
                                .equalToValue(
                                       true)))
                        .as("closedProblems");
     aggregators.add(match);
     aggregators.add(project);
     Aggregation aggregation = newAggregation(aggregators).withOptions(newAggregationOptions().cursor(new Document()).build());
     AggregationResults<Document> results = mongoTemplate.aggregate(aggregation, "myColl", Document.class );
     for (Document result : results) {
                    // ...
    }
}

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

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