【问题标题】:MongoDB MapReduce report generationMongoDB MapReduce 报告生成
【发布时间】:2026-01-13 23:35:02
【问题描述】:

我有以下布局:

{
    "URL": "http://someurl.de",
    "plugins": {
        "HTTPServer": {
            "os": [
                "FreeBSD"
            ],
            "string": [
                "Apache/2.2.21 (FreeBSD) mod_ssl/2.2.21 OpenSSL/0.9.8q DAV/2 PHP/5.3.8 with Suhosin-Patch"
            ]
        }
    }
}

我想从中获取存储在 plugins.HTTPServer.string 中的唯一项的计数。然而,所有 MapReduce 示例都仅引用单级文档。据我了解这些示例,您必须在 map 函数中发出数据(或选择要提取的数据),然后使用 reduce 进一步处理结果。我认为我的问题是在映射阶段 - 我需要访问上面的字符串值:“Apache/2.2...”

由于我只在 MongoDB 中度过了最后一天,如果我没有在这里提出正确的问题,请原谅我的无知。我是否朝着正确的方向前进?我知道我可以使用 distinct = db.coll.distinct('plugins.HTTPServer.string'),但我想用 MapReduce 来完成。

map = function() {
  server = this.plugins.HTTPServer.string
  emit({server : this.server}, {count: 1});
}

reduce = "function(key, values) {
  var count = 0;

  values.forEach(function(v) {
    count += v['count'];
  });

  return {count: count};
}"

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    你有几个问题:

    1. this.servermap 函数的发射中应该只是server
    2. 在您的文档中,"string" 字段是一个数组,而不是单个字符串,因此您将数组作为键发出,这可能不是您想要的。
    3. " 函数中有杂散的 " 字符。

    试试这个:

    var map = function() {
      if (this.plugins && this.plugins.HTTPServer && this.plugins.HTTPServer.string) {
        this.plugins.HTTPServer.string.forEach(function(server) {
          emit({server: server}, {count: 1});
        });
      }
    }
    
    var reduce = function(key, values) {
      var count = 0;
    
      values.forEach(function(v) {
        count += v['count'];
      });
    
      return {count: count};
    }
    

    【讨论】:

    • 谢谢,会试一试并回复你,看起来我错过了范围特异性
    • 有些东西似乎仍然不对劲-> 12 月 5 日星期三 01:01:47 [conn93] JS 错误:TypeError: this.plugins.HTTPServer 没有属性 nofile_b:1 12 月 5 日星期三 01:01:47 [ conn93] mr 失败,删除集合 :: 由 :: 9014 映射调用失败:JS 错误:TypeError:this.plugins.HTTPServer 没有属性 nofile_b:1
    • 即使尝试以下语法 conks: this['plugins.HTTPServer.string'] has no properties
    • @ForkrulAssail 听起来您的收藏中有些文档不包含plugins.HTTPServer.string,这可能吗?
    • @ForkrulAssail 我更新了答案以适应这种情况,不为那些缺少的文档发出。试试看。