只读一个JSON文档和联合(BigData?)

时间:2016-03-29 19:27:28

标签: javascript mapreduce couchdb bigdata

我需要阅读许多JSON文档并进行合并才能生成一个文档。

让我解释一下:我有一个跟踪系统,可以从网站的用户导航中捕获许多事件。我可以使用属性ID来映射相关文档并创建合并文档。

实施例

我的输入:

{
    id: "12345"
          fly :
             "nyc-bos", time: "10:00am"
             "orl-mia", time: "09:00am"
             "chi-mem", time: "07:00am"
          order :
             "099300"
             "677800"
             "129999"
          product :
             "DVD"
             "LCD TV"
}

我需要这样的文件:

"https://www.facebook.com/v2.5/dialog/oauth?client_id=*****&state=*****&response_type=code&sdk=php-sdk-5.1.2&redirect_uri=http%3A%2F%2Flocalhost%3A8888%2Ffacebook%2Flink&scope=email%2Cuser_birthday%2Cuser_photos"

重要的:

  • 我有数百万的输入文件
  • 我不能使用BigData框架(Hadoop等)
  • 我的堆栈受到限制(Windows + C#+ CouchDB)

有人有我可以遵循的想法吗?

由于

3 个答案:

答案 0 :(得分:0)

你只需要在地图/缩小版中执行此操作,只为您的地图创建一个简单的emit(doc.id, doc),然后为缩小版本执行以下操作:

function( keys, values, rereduce ) {
  var doc = {};
  values.forEach( function(d) {
    var dd = doc[d.id] = doc[d.id] || {};

    if(d.fly) {
      dd['fly'] = dd['fly'] || [];
      dd.fly.push({ code: d.fly, time: d.time });
    }
    else if(d.order) {
      dd['order'] = dd['order'] || [];
      dd.order.push(d.order);
    }
    else if(d.product) {
      dd['product'] = dd['product'] || [];
      dd.product.push(d.product);
    }
  });
  return doc;
}

请注意,我使用code作为fly对象中的密钥,但您无法在JSON中使用"nyc-bos", time: "10:00am",这两个值都需要有密钥。

答案 1 :(得分:0)

您所看到的是数据汇总,可以使用couchdb利用名为“views”和“lists”的两个概念来实现。你的技术堆栈应该不是问题,因为从概念上你可以使用httpclient与couchdb进行交互。我建议你先阅读沙发视图, https://wiki.apache.org/couchdb/Introduction_to_CouchDB_views http://guide.couchdb.org/draft/views.html 一旦你熟悉它们,你就可以输出一个数据集,如你的第一个片段所示,那就是沙发'list'功能将扮演它的角色,聚合数据并输出你的第二个片段中的某种格式。基本上,列表函数位于管道中的视图函数旁边,它们将被提供视图函数的输出。通过阅读官方的couchdb文档,您可以更深入地理解这个概念。为方便起见,请参阅以下链接。 http://guide.couchdb.org/draft/transforming.html

如果需要为文档输出统计数据集(couch reduce functions),它可能看起来像这样

{ "rows":
   [
     {"key":"de", "value":{"sum":2,"count":2,"min":1,"max":1,"sumsqr":2}},
     {"key":"ee", "value":{"sum":2,"count":2,"min":1,"max":1,"sumsqr":2}},
     {"key":"de", "value":{"sum":2,"count":2,"min":1,"max":1,"sumsqr":2}},
     {"key":"ee", "value":{"sum":2,"count":2,"min":1,"max":1,"sumsqr":2}},
     {"key":"de", "value":{"sum":2,"count":2,"min":1,"max":1,"sumsqr":2}}
   ]
}

并聚合它们,以便我们可以输出具有唯一键但聚合值(min,max等)的数据集,我们可以编写如下列表函数

function(head, req) {
  var row;
  var result = [];
  var firstRun = true;
  var found = true;
  start({
    "headers": {
      "Content-Type": "application/json"
     }
  });

while(row = getRow()) {      
      if(firstRun){
          firstRun = false;
          result.push({id: row.key, sum: row.value.sum, count: row.value.count, min: row.value.min, max: row.value.max, sumsqr: row.value.sumsqr});
      }else{
        for (var i = 0; i < result.length; i++) {
          if (row.key === result[i].id) {
              result[i].sum += row.value.sum;
              result[i].count += row.value.count;
              result[i].min = ((row.value.min < result[i].min) ? row.value.min : result[i].min);
              result[i].max = ((row.value.max > result[i].max) ? row.value.max : result[i].max);
              result[i].sumsqr = result[i].sum;
              found = true;
            break;
          }else{
            found = false;
          }
        }      
      }
    if(!found){
        result.push({id: row.key, sum: row.value.sum, count: row.value.count, min: row.value.min, max: row.value.max, sumsqr: row.value.sumsqr});
        found = true;
    }
  } return JSON.stringify(result);
}

答案 2 :(得分:0)

这是所谓的Map/Reduce "collation"的典型案例。

注意:由于id具有误导性(使用_id,文档标识符),我将其称为user_id

首先,您必须发出校对键,没有值(从不发出doc作为值。索引越轻,越好。自动完成原始文档的链接)。我们还会将类别添加到密钥中,因为您希望对结果进行排序。

function(o) {
    if (o.fly) {
      emit([o.user_id, 'fly']);
    } else if (o.order) {
      emit([o.user_id, 'order']);
    } else if (o.product) {
      emit([o.user_id, 'product']);
    }
}

不要定义reduce函数,因为您要保留指向原始文档的链接。

使用include_docs=true查询您的观点以获取链接的文档,并选择startkeyendkey的用户:

/mydb/_design/mydesign/_view/myview?include_docs=true&startkey=["12345"]&endkey=["12345",{}]

你会得到:

[
{"key":["12345", "fly"], "value": null, "doc":{"user_id": "12345", "fly":"nyc-bos", "time":"10:00am"}},
{"key":["12345", "fly"], "value": null, "doc":{"user_id": "12345", "fly": "orl-mia", "time": "09:00am"}},
{"key":["12345", "fly"], "value": null, "doc":{"user_id": "12345", "fly": "chi-mem", "time": "07:00am"}},
{"key":["12345", "order"], "value": null, "doc":{"user_id": "12345", "order": "099300"}},
{"key":["12345", "order"], "value": null, "doc":{"user_id": "12345", "order": "677800"}},
{"key":["12345", "order"], "value": null, "doc":{"user_id": "12345", "order": "129999"}},
{"key":["12345", "product"], "value": null, "doc":{"user_id": "12345", "product": "DVD"}},
{"key":["12345", "product"], "value": null, "doc":{"user_id": "12345", "product": "LCD TV"}}
]

所有繁重的计算(a.k.a。“限制”,“加入”和“排序”)都是由Map / Reduce完成的。然后,您可以使用简单的list function调整格式。