如何使用mongodb java驱动程序3.2从mapReducet获取内联结果?
使用驱动程序版本2.x我正在做:
DBColleciont coll = client.getDB(dbName).getCollection(collName);
coll.mapReduce(map, reduce, null, OutputType.INLINE, query);
新的3.x驱动程序有两个 mapReduce()方法返回 MapReduceIterable ,它错过了指定INLINE输出模式的方法。
MongoCollection<Documetn> coll = client.getDatabase(dbName).getCollection(collName)
coll
.mapReduce(map, reduce).
.filter(query);
答案 0 :(得分:3)
您可以手动创建map-reduce命令:
String mapFunction = ...
String reduceFunction = ...
BsonDocument command = new BsonDocument();
BsonJavaScript map = new BsonJavaScript(mapFunction);
BsonJavaScript red = new BsonJavaScript(reduceFunction);
BsonDocument query = new BsonDocument("someidentifier", new BsonString("somevalue"));
command.append("mapreduce", new BsonString("mySourceCollection"));
command.append("query", query);
command.append("map", map);
command.append("reduce", red);
command.append("out", new BsonDocument("inline", new BsonBoolean(true)));
Document result = mongoClient.getDatabase(database).runCommand(command);
我认为这非常难看,但它是我迄今为止使用3.2找到的唯一可行解决方案。 (......并且对一个更好的变体非常感兴趣......; - ))
答案 1 :(得分:2)
我想我发现了...... 我深入研究了mongodb的Java驱动程序源代码,似乎可以隐式访问INLINE输出功能:
class MapReduceIterableImpl<TDocument, TResult>
(MapReduceIterableImpl.java),它是接口返回类型mapReduce()
的默认实现,
保留private boolean inline
,初始值为true
。
唯一可以切换到false
的地方是方法collectionName(final String collectionName)
,其描述如下:
为MapReduce的输出设置collectionName 默认操作是替换集合(如果存在),以更改此使用操作(com.mongodb.client.model.MapReduceAction)。
如果你从未在mapReduce()
之后在对象实例上调用此方法,它将保持true
初始化...意思是:如果没有输出集合,则它必须是内联的。
稍后,当您在内部使用iterator(), first(), forEach(...)
等访问结果时,会调用execute()
方法,该方法具有神奇的if
条件:
if (inline) {
MapReduceWithInlineResultsOperation<TResult> operation =
new MapReduceWithInlineResultsOperation<TResult>(namespace,
new BsonJavaScript(mapFunction),
new BsonJavaScript(reduceFunction),
codecRegistry.get(resultClass))
.filter(toBsonDocument(filter))
.limit(limit)
.maxTime(maxTimeMS, MILLISECONDS)
.jsMode(jsMode)
.scope(toBsonDocument(scope))
.sort(toBsonDocument(sort))
.verbose(verbose)
.readConcern(readConcern);
....
} else {
MapReduceToCollectionOperation operation =
new MapReduceToCollectionOperation(namespace, new BsonJavaScript(mapFunction), new BsonJavaScript(reduceFunction),
collectionName)
.filter(toBsonDocument(filter))
.limit(limit)
.maxTime(maxTimeMS, MILLISECONDS)
.jsMode(jsMode)
.scope(toBsonDocument(scope))
.sort(toBsonDocument(sort))
.verbose(verbose)
.action(action.getValue())
.nonAtomic(nonAtomic)
.sharded(sharded)
.databaseName(databaseName)
.bypassDocumentValidation(bypassDocumentValidation);
...因此,当MapReduceWithInlineResultsOperation
未被调用时,它正在实现collectionName()
。
我没有机会测试它,因为我的NetBeans目前讨厌我,但我认为这很清楚。 你觉得怎么样,我错过了什么?
如果我可以帮助您将代码转移到API 3.x,那就太棒了!很棒的项目!