2016-01-29 50 views
0

我有一个计数字的问题 我想在projects.log.subject中计算单词。 ex)count [A],[B],[C] .. 我搜索了如何使用map reduce ..但我不明白如何将它用于我想要的结果。Mongodb使用地图的字数减少

{ 
"_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 
+0

所以'[A],[B]'和'[C]'代表你想要查找的单词,并最终返回每个单词出现在所有文档中的次数。正确?您是否至少在mapReduce上做了一些基础研究,并了解mapper和reducer函数的工作原理?这总是在“projects”数组内的“log”字段内? –

+0

@BlakesSeven 1.是的,我想要计算特定文档中每个单词的次数(如{'$ match':{'date':TODAY}}。 2。我了解地图,减少功能工作 3.是所有文件中都有相同的结构[项目] [日志] [主题] – Acool5

回答

0

这是使用正则表达式和测试对源串中的每个串并发射用于结果所找到的计数的一个基本原则。在mapReduce术语中,您希望您的“映射器”函数可能为每个“术语”作为关键字以及每个文档中存在的每个数组元素发出多个值。

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

基本上是这样的:

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,那么我们将当前词作为“键”,将计数作为匹配数组的长度。

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

结果将会是由提供的每个“单词/词语”键入的一个文档以及该集合中被检查字段中的总发生次数。对于更多的领域,只需添加更多的逻辑来总结结果,或者类似地只需在映射器中“发射”并让减速器完成工作。

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

此外,由于正则表达式,如[]字符被保留,所以如果你真的正在寻找串一样的是,你同样逃脱,即:

"\[A\]" 

但是,如果你确实这样做,然后取出字边界字符:

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

因为这是足够的完全匹配本身。

+0

谢谢。有用!非常感谢你 但你提到[]是保留的权利? 所以我尝试了新的RegExp(“\ [”+ word +“\”“,”ig“) ,但它不起作用。 – Acool5

+0

@ Acool5我已经提到了“转义”保留字符,并给出了一个字面示例。但是在直接翻译中,如果你确实在总是包含在括号'[]'中的变量中寻找一个“单词”,则这是'RegExp(“\ [”+ word +“\]”,“ig”)''。 –