Morphia Complex Mongodb 聚合($substr、$project、$sort 等...)

Morphia Complex Mongodb Aggregate ($substr, $project, $sort, etc...)

我正在使用 Java 的 Morphia 库。

通过命令行客户端,我能够成功执行以下聚合

db.shows.aggregate([
    {$project: {
        _id: 1,
        title: 1
    }},
    {$group:
        {
            _id: {titleLetter: {$substr: ["$title", 0, 1]}},
            count: {$sum: 1},
            shows: {$push: "$title"}
        }
    },
    {$sort: {_id: 1}}
]);

这给了我一个按节目标题的第一个字母分组的节目列表。

在吗啡的官方 docs 上,我看到他们可以接受 DBObject AdvancedDatastore.createQuery,但我没有看到任何类似的聚合。

也许我会使用类似

的东西
BasicDBObject parse = (BasicDBObject) JSON.parse("{$group: { _id: {titleLetter: {$substr: [\"$title\", 0, 1]}}, count: {$sum: 1}, shows: {$push: \"$title\"} } }");

同样还有BasicDBObjectBuilder方法

DBObject group = BasicDBObjectBuilder.start().push("$group")
        .add("_id", "{titleLetter: {$substr: [\"$title\", 0, 1]}}")
        .get();

所以我可以将 CLI 查询转换为 Morphia 或至少从 import com.mongodb.*; 到 Java 可以理解的东西。

我无法使用任何方法将此查询从 Java 获取到 运行。

我的问题是什么是将我在 cli 中的聚合查询转换为 Java 中的查询的干净方法,并且最终会 return a Java object ?

创建 InputOutputMain class,如下所示。

Main class 创建 Cli 查询的 Morphia 等效项并提供输入和输出 class。

Morphia 负责验证和映射 mongo 数据到请求和响应。

输入Class

package org.mongodb.morphia;
import org.bson.types.ObjectId;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
import java.io.Serializable;

@Entity("Input")
public class Input implements Serializable {
    @Id
    private ObjectId id;
    private String title;
  //Getters and Setters
}

输出Class

package org.mongodb.morphia;
import java.util.List;
public class Output {
    private int count;
    private List<String> shows;
 //Getters and Setters
}

主要Class

package org.mongodb.morphia;
import com.mongodb.MongoClient;
import org.mongodb.morphia.aggregation.AggregationPipeline;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import static org.mongodb.morphia.aggregation.Accumulator.accumulator;
import static org.mongodb.morphia.aggregation.Group.*;
import static org.mongodb.morphia.aggregation.Projection.projection;
import static org.mongodb.morphia.query.Sort.descending;

public class MorphiaClient {
    public static void main(String[] args) {
        final Morphia morphia = new Morphia();
        morphia.mapPackage("org.mongodb.morphia");
        final Datastore datastore = morphia.createDatastore(new MongoClient(), "test");
        AggregationPipeline pipeline = datastore.createAggregation(Input.class).
                project(projection("id"), projection("title")).
                group(id(grouping("titleLetter", accumulator("$substr", Arrays.asList("$title", 0, 1)))),
                        grouping("count", accumulator("$sum", 1)),
                        grouping("shows", accumulator("$push", "title"))).
                sort(descending("id"));
        List<Output> results = new ArrayList<>();
        Iterator<Output> iterator = pipeline.aggregate(Output.class);
        while (iterator.hasNext()) {
            results.add(iterator.next());
        }
    }
}