我正在MongoDB中编写一个map reduce函数,该函数将在多个集合中使用。每个集合上的map reduce结果将结果合并到同一个输出集合中。
我想要:
- 如果在不同的源文档中找到相同的关键字,则在关键字中包括文档所属的集合的名称,以便输出集合包含一个单独的文档
- 映射函数引用集合的名称,而无需对其进行硬编码,这样就不必为包含相同逻辑的四个集合编写四个不同的映射函数(即保持映射函数DRY)
这可能吗?
以下是更多详细信息。。。
地图功能:
function() {
emit({ cpID: this.cpID, institutionID: this.institutionID, sourceCollection: collName }, 1);
};
减少功能:
function(key, values) {
return values.length;
};
mongo shell命令:
db.loadServerScripts();
var collName;
collName = "activities";
db.activities.mapReduce(mapcpsinstitutions, reducecpsinstitutions, { out: {replace: "cpsAndSchools"}, "scope": { "collName": collName } } );
collName = "activitysummaries";
db.activitysummaries.mapReduce(mapcpsinstitutions, reducecpsinstitutions, { out: {reduce: "cpsAndSchools"}, "scope": { "collName": collName } } );
collName = "contentusagesummaries";
db.contentusagesummaries.mapReduce(mapcpsinstitutions, reducecpsinstitutions, { out: {reduce: "cpsAndSchools"}, "scope": { "collName": collName } } );
collName = "contentusages";
db.contentusages.mapReduce(mapcpsinstitutions, reducecpsinstitutions, { out: {reduce: "cpsAndSchools"}, "scope": { "collName": collName } } );
这在您的实际意图中似乎有点模糊。但是,从保留一个奇异的"map"函数的基本概念来看,该函数将使用一个"变量"名称作为发出的"密钥"的一部分,那么您可以始终使用mapReduce的"scope"选项:
var colname = "collection";
db.getCollection(colname).mapReduce(
function() {
var data = {};
// Some map operations here
emit( collection + idKey, data );
},
function(key,values) {
var reduced = {};
// Reduce operations here
return reduced;
},
{
"out": { "merge": "newcollection" },
"scope": { "collection": colname }
}
)
因此,"scope"中定义的任何内容都是您可以提供的"map"、"reduce"one_answers"finalize"函数的"全局"变量。可以通过这种方式传递变量,而无需更改任何这些函数的代码。
这里的基本情况是将当前集合名称"预挂起"到发出的密钥