是否可以在MongoDB映射函数中包含映射集名称的名称作为键的一部分?

时间:2014-11-05 20:38:02

标签: javascript mongodb mapreduce mongodb-query

我正在MongoDB中编写一个map-reduce函数,该函数将用于多个集合。每个集合上map-reduce的结果将结果合并到相同的输出集合中。

我想:

  • 在密钥中包含文档所在的集合的名称,以便在不同的源文档中找到相同的密钥时,输出集合包含单独的文档
  • map函数引用集合的名称而不对其进行硬编码,因此不必为包含相同逻辑的四个集合编写四个不同的映射函数(即保持映射函数DRY)< / LI>

这可能吗?

以下更多细节......

地图功能:

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

1 个答案:

答案 0 :(得分:1)

这在你的实际意图中似乎有点模糊。但是从保持单一“地图”功能的基本概念出发,使用“变量”名称作为发出的“密钥”的一部分,那么你总是可以使用mapReduce的“范围”选项:

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

因此,“范围”中定义的任何内容都是您可以提供的“map”,“reduce”和“finalize”函数的“全局”变量。变量可以这种方式传递,而无需改变任何这些函数的代码。

这里的基本情况是将当前集合名称“预先挂起”到发出的密钥