0

我在使用非常简单的 mapreduce 时遇到了一些麻烦,我不知道我做错了什么。我正在尝试将两个集合合并在一起,首先,db.Pos 看起来像这样

"chr" : "chr1", "begin" : 39401, "end" : 39442

另一个集合 db.Gene 具有以下格式

"chr" : "chr1", "begin" : 39401, "end" : 39442, "gene" : "GENE1"

我的代码如下所示:

var mapPos = function(){

    emit({chr: this.chr, begin:this.begin, end:this.end},{gene:""});

}

var mapGene = function() {

    emit({chr: this.chr, begin:this.begin, end:this.end},{gene:this.gene});
}

r = function(key,values){

    var result = {gene:""}
    values.forEach(function(value){

    result.gene = value.gene;

});

return result;

}

res = db.Pos.mapReduce(mapPos, r, {out: {reduce: 'joined'}});
res = db.Gene.mapReduce(mapGene, r, {out: {reduce: 'joined'}});

所以我想看到的是一个集合,其中与 chr、begin 和 end 匹配的条目被合并,并且基因字段是从 db.Gene 集合中填充的。

相反,即使 db.Gene 中没有具有基因字段的匹配文档,我的“已加入”集合中的“基因”字段也会更新为 0 以外的值。

我做错了什么?

4

1 回答 1

0

经过反思,我认为你应该使用merge而不是reduce为你的out.


您没有良好价值的原因:

问题是在joined集合内容和db.Gene.mapReduce.

该函数reduce不知道哪个值是最新的,因此result.gene返回的是数组的最后value.gene一个values

要区分将覆盖集合中现有值的值,您可以添加一个标志。

res = db.Pos.mapReduce(
    function() {
        emit({chr: this.chr, begin:this.begin, end:this.end},{gene:this.gene || ''});
    }, 
    function(key,values){
        var result = {};
        values.forEach(function(value){
            if (value)
                result.gene = value.gene;
        });
    }, 
    {out: {reduce: 'joined'}}
);

res = db.Gene.mapReduce(
    function() {
        //Add a flag override here
        emit({chr: this.chr, begin:this.begin, end:this.end},{gene:this.gene || '', override: true});
    }, 
    function(key,values){
        var result = {};
        values.forEach(function(value){
            if (value.override)
                result.gene = value.gene;
        });
        return result;
    }, 
    {out: {reduce: 'joined'}}
);

希望很清楚:)

于 2013-12-05T10:21:10.957 回答