【问题标题】:Mongodb word count using map reduce使用 map reduce 的 Mongodb 字数统计
【发布时间】:2016-01-29 02:10:55
【问题描述】:

我在数单词时遇到问题 我想计算projects.log.subject 中的单词。 例如)计数 [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

【问题讨论】:

  • 所以[A] ,[B][C] 表示您要查找的单词并最终返回每个单词在所有文档中出现的次数。正确的?你是否至少对 mapReduce 做过一些基础研究,并了解 mapper 和 reducer 函数是如何工作的?这总是在“项目”数组中的同一个“日志”字段中?
  • @BlakesSeven 1. 是的,我想计算特定文档中每个单词的次数(例如 {'$match':{'date':TODAY}}。2. 我了解地图, reduce 功能有效 3. 是的,所有文档 [projects][log][subject] 中的结构始终相同

标签: regex mongodb mapreduce mongodb-query


【解决方案1】:

这是使用正则表达式并针对源字符串测试每个字符串并为结果发出找到的计数的基本原则。在 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,那么我们将当前单词作为“键”,并将计数作为匹配数组的长度。

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

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

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

另外,作为正则表达式,[] 这样的字符是保留的,所以如果你真的在寻找这样的字符串,你同样会转义,即:

"\[A\]"

但如果你真的这样做了,那么删除单词边界字符:

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

因为这本身就足够了。

【讨论】:

  • 谢谢。有用!非常感谢 但是您提到 [] 是保留的,对吗?所以我尝试了 new RegExp("["+word+"]","ig") 但它不起作用。
  • @Acool5 我确实已经提到“转义”保留字符并且还给出了一个文字示例。但在直接翻译中,如果您确实要在变量中查找始终包含在括号中的“单词”[],则为 []
猜你喜欢
  • 2013-05-25
  • 1970-01-01
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-01
  • 1970-01-01
相关资源
最近更新 更多