Couchdb reduce函数 - 仅返回满足特定条件的和(值)

时间:2014-05-04 11:17:16

标签: mapreduce couchdb reduce


我是Couchdb的新手,目前我在使用couchdb map-reduce功能时遇到了一个很小的(可能......)问题,因为我在网上找不到任何相关的信息。我在这里为自己寻求帮助。
基本上情况是这样的:我使用map函数来计算某个doc中出现的某个单词的时间。发射就像:

emit(word,1)

通过这种方式,如果我需要得到每个单词的总和值,以便弄清楚每个单词在所有文档中出现的次数。我可以简单地编写reduce函数代码,如:

function(key, values, rereduce)
{
    return sum(values);
}

但我真正的需要是只返回大于3000的总和(值)(找出在所有文档中出现超过3000次的单词)。所以我试着这样做:

function(key, values, rereduce)
{
    if(sum(values)>3000)
    return sum(values);
}

但是这样,所有出现少于3000次的单词仍然会返回,但值为null。我知道这是因为reduce函数必须返回一些内容,因此当'if'语句不匹配时,它必须返回null。但有没有人可以给我这方面的有用建议 - 如何返回仅满足某些条件的总和(值)......

1 个答案:

答案 0 :(得分:1)

可能不可能

我不认为你想做的事情是可能的。所有reduce函数都是使用相同的键对多个文档中的字数进行聚合/求和,它将始终为您在map函数中生成的所有键返回一些内容。

考虑减少/减少

即使你可以接受'null'的代码,你也有潜在的错误。请仔细阅读:https://wiki.apache.org/couchdb/Introduction_to_CouchDB_views#Reduce_vs_rereduce

假设您有一千个密钥的发射,这些发射的子集可能会在较小的分段中减少,然后在所有分段的rereduce函数中重新访问。

除非这些段(其大小由couchdb管理)是> 3000个元素,你的查询可能意味着你将生成很多'null',然后重新减少它们。如果您的代码应该读取任何内容:

    function(key, values, rereduce)
    {
        if(rereduce && sum(values)<3000){return 0;}
        return sum(values);
    }

其他设置

我假设您的文档中有太多单词无法查询所有单词。我测试你是否可以使用单词的一部分作为键,所以例如,如果你有一个单词“couch”和“couchdb”,你会发出这些作为文件的一部分,用“co”或“cou”键“等等

    { "couch" :  1, "couchdb" : 15 } 

你仍然可以解析有限数量的密钥并在rereduce上应用3000规则。但是,在减少调用之后,您有可能会对值的大小违反以下经验法则:

https://wiki.apache.org/couchdb/Introduction_to_CouchDB_views#reduced_value_sizes

<强>声明

对于全文搜索问题的类型,您可能需要查看couchdb-lucene。 (我没有使用它,所以不知道你是否能够解决你的问题。)