Mongodb字数使用map reduce

时间:2016-01-29 02:10:55

标签: regex mongodb mapreduce mongodb-query

我有计算单词的问题 我想在projects.log.subject中计算单词。 ex)计数[A],[B],[C] .. 我搜索了如何使用map reduce ..但我不明白如何使用它来获得我想要的结果。

{
"_id": ObjectID("569f3a3e9d2540764d8bde59"),
"A": "book",
"server": "us",
"projects": [
    {
        "domainArray": [
            {
                ~~~~
            }
        ],
        "log": [
            {
                ~~~~~,
                "subject": "[A][B]I WANT THIS"
            }
        ],
        "before": "234234234"
    },
    {
        "domainArray": [
            {
                ~~~~
            }
        ],
        "log": [
            {
                ~~~~~,
                "subject": "[B][C]I WANT THIS"
            }
        ],
        "before": "234234234"
    },....
] //end of projects
}//end of document

1 个答案:

答案 0 :(得分:1)

这是使用正则表达式并针对源字符串测试每个字符串并为结果发出找到的计数的基本原则。在mapReduce术语中,您需要" mapper"函数可能为每个" term"发出多个值。作为键,以及每个文档中存在的每个数组元素。

所以你基本上想要一个正则表达式的源数组来处理(可能只是一个单词列表)来迭代和测试并迭代每个数组成员。

基本上是这样的:

db.collection.mapReduce(
    function() {
        var list = ["the", "quick", "brown" ];  // words you want to count

        this.projects.forEach(function(project) {
            project.log.forEach(function(log) {
                list.forEach(function(word) {
                    var res = log.subject.match(new RegExp("\\b" + word + "\\b","ig"));
                    if ( res != null )
                        emit(word,res.length);  // returns number of matches for word
                });
            });
        });
    },
    function(key,values) {
        return Array.sum(values);
    },
    { "out": { "inline": 1 } }
)

因此循环处理文档中的数组元素,然后应用每个单词以查找正则表达式进行测试。如果找到完成,.match()方法将返回字符串中的匹配数组或null。请注意正则表达式的ig选项,以便搜索不区分大小写且超出第一个匹配项。如果您的文字也包含换行符,则可能需要m作为多行。

如果未返回null,则我们将当前单词作为"键"并将计数作为匹配数组的长度。

然后,reducer将从映射器中的emit个调用中获取所有输出值,并简单地将发出的计数相加。

结果将是每个" word / term"键入的一个文档。提供了集合内被检查领域的总发生次数。对于更多字段,只需添加更多逻辑来总结结果,或者类似地保持"发出"在映射器中让减速器完成工作。

注意"\\b" represents a word boundary expression to wrap each term escaped by`以便从字符串构造表达式。例如,您需要通过指定单词/术语结束的位置来区分"the""then"

另外,作为正则表达式,[]这样的字符是保留的,所以如果你真的在寻找类似的字符串,那么你也可以逃避,即:

"\[A\]"

但如果您实际上是这样做,那么删除单词边界字符:

new RegExp( "\[A\]", "ig" )

因为这本身就足以完全匹配。