如何使用Apache Spark JavaRDDs在MongoDB中查询?

时间:2017-02-16 22:13:38

标签: java mongodb apache-spark

我想想象现有的API功能。假设Java代码看起来像这样:

JavaRDD<Integer> queryKeys = ...; //values not particularly important

List<Document> allMatches = db.getCollection("someDB").find(queryKeys); //doesn't work, I'm aware

JavaPairRDD<Integer, Iterator<ObjectContainingKey>> dbQueryResults = ...;

目标:在一堆数据转换后,我最终得到一个整数键的RDD,我想根据这个键集合进行单个数据库查询(而不是一堆查询)。

从那里开始,我想将查询结果转换为密钥的一对RDD,并将其所有结果转换为迭代器(这样我就可以轻松地完成后续步骤了解我打算采取的措施)。澄清一下,我的意思是一对密钥及其作为迭代器的结果。

我知道MongoDB中的功能能够与Spark协调,但我还没有找到任何可以解决这个问题的东西(它似乎倾向于写入数据库而不是查询它)。

1 个答案:

答案 0 :(得分:0)

我设法以足够有效的方式解决这个问题。

JavaRDD<Integer> queryKeys = ...;
JavaRDD<BasicDBObject> queries = queryKeys.map(value -> new BasicDBObject("keyName", value));
BasicDBObject orQuery = SomeHelperClass.buildOrQuery(queries.collect());
List<Document> queryResults = db.getCollection("docs").find(orQuery).into(new ArrayList<>());

JavaRDD<Document> parallelResults = sparkContext.parallelize(queryResults);
JavaRDD<ObjectContainingKey> results = parallelResults.map(doc -> SomeHelperClass.fromJSONtoObj(doc));
JavaPairRDD<Integer, Iterable<ObjectContainingKey>> keyResults = results.groupBy(obj -> obj.getKey());

这里的方法buildOrQuery

public static BasicDBObject buildOrQuery(List<BasicDBObject> queries) {
    BasicDBList or = new BasicDBList();
    for(BasicDBObject query : queries) {
        or.add(query);
    }
    return new BasicDBObject("$or", or);
}

请注意,有一个fromJSONtoObj方法可以将您的对象从JSON转换回所有必需的字段变量。另请注意,obj.getKey()只是一个与任何“键”关联的getter方法。