Morphia Complex Mongodb Aggregate($ substr,$ project,$ sort等)

时间:2017-02-25 23:43:41

标签: java mongodb morphia

我正在使用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}}
]);

通过节目标题的第一个字母给出了一个节目组列表。

在morphia的官方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中的查询并最终返回Java对象的干净方法是什么?

1 个答案:

答案 0 :(得分:2)

创建InputOutputMain类,如下所示。

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

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

输入类

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
}

输出类

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

主类

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