使用 java mongodb 驱动程序 3.2 的 mapReduce 内联结果
mapReduce inline results with java mongodb driver 3.2
如何使用 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);
您可以手动创建 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 发现的唯一可行的解决方案。 (...并且也会对更好的变体非常感兴趣...;-))
我想我找到了...
我深入研究了 mongodb 的 Java 驱动程序源,似乎可以隐式访问 INLINE 输出功能:
class MapReduceIterableImpl<TDocument, TResult>
(MapReduceIterableImpl.java),这是mapReduce()
接口return类型的默认实现,
持有初始值为 true
.
的 private boolean inline
唯一可以切换到 false
的地方是方法 collectionName(final String collectionName)
,其描述如下:
Sets the collectionName for the output of the MapReduce
The default action is replace the collection if it exists, to change this use action(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);
...因此在 collectionName()
未被调用时实例化 MapReduceWithInlineResultsOperation
。
我没有机会测试它,因为我的 NetBeans 此刻讨厌我,但我认为它很清楚。
你觉得怎么样,我是不是漏掉了什么?
如果我能帮助您将代码转移到 API,我会很高兴 3.x,伟大的项目!
如何使用 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);
您可以手动创建 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 发现的唯一可行的解决方案。 (...并且也会对更好的变体非常感兴趣...;-))
我想我找到了... 我深入研究了 mongodb 的 Java 驱动程序源,似乎可以隐式访问 INLINE 输出功能:
class MapReduceIterableImpl<TDocument, TResult>
(MapReduceIterableImpl.java),这是mapReduce()
接口return类型的默认实现,
持有初始值为 true
.
private boolean inline
唯一可以切换到 false
的地方是方法 collectionName(final String collectionName)
,其描述如下:
Sets the collectionName for the output of the MapReduce The default action is replace the collection if it exists, to change this use action(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);
...因此在 collectionName()
未被调用时实例化 MapReduceWithInlineResultsOperation
。
我没有机会测试它,因为我的 NetBeans 此刻讨厌我,但我认为它很清楚。 你觉得怎么样,我是不是漏掉了什么?
如果我能帮助您将代码转移到 API,我会很高兴 3.x,伟大的项目!