1

我正在尝试与 Rethinkdb 一起使用 mapreducing 类似的东西: [{"a":1, "b":2}, {"a":3}, {"c":4}]to {"a":[1,3], "b":[2], "c":[4]}.

我已经咨询过Javascript:如何将对象数组转换为具有排序唯一数组的对象?但是这些语句在 ReQL 中并不能真正起作用,这里有一个例子:

r.expr([{"a":1, "b":2}, {"a":3}, {"c":4}]).do(function(user){
  var c1 = {};
    var keys = ["a", "b", "c"];      

    user.map(function(itm){
      keys.map(function(p){
        if(!c1[p]){
          c1[p] = [];
        };
        c1[p] = r.expr(c1[p]).setInsert(itm(p).default("NIL"));
      });
      return 1
    });
  return c1
});

但这在 itm(p) 上出现错误并出现错误:RqlCompileError: Variable name not found in:

RqlCompileError: Variable name not found in:
r([{a: 1, b: 2}, {a: 3}, {c: 4}]).do(function(var_136) { return {a: r([]).setInsert(var_137("a").default("NIL")), b: r([]).setInsert(var_137("b").default("NIL")), c: r([]).setInsert(var_137("c").default("NIL"))}; })
                                                                                    ^^^^^^^                                                                                                                            

因为 rethinkdb 将变量 id(在本例中为 137)分配给未事先声明的 itm(p)。

有什么想法我该怎么做?

谢谢

4

2 回答 2

3

改编github 上 danielmewes的答案

var input = r.expr([{"a":1}, {"a":3}, {b: 2}, {"a":4}, {b: 3}]);
var keys = input.map(function(x){return x.keys()})
  .reduce(function(l, r){return l.setUnion(r)});
  .map(function(key){ return [key, input(key)]})
  .coerceTo('object');

由于这使用了一些高级 ReQL 技术,以下是它的分解方式:

  1. 首先,我们获取数组中每个对象的键。这导致数组数组
  2. 接下来我们减少,这对来自前一个数组的元素进行成对组合。我们最终得到的是原始数组中任何对象中所有键的去重列表。
  3. 接下来,对于每个键,我们创建一个双元素数组,其中第一个元素是键,第二个元素是原始输入中具有该键的所有值的数组。
    • 这是有效的,因为()reql 比常规的 javascript[]括号更强大。它将使用该键收集字段的值。
    • 此步骤的输出是一个数组数组,例如[['a', [1,2]], ['b', [3,4]]
  4. 最后,我们强制一个对象。ReQL 可以将数组强制[['a', 1], ['b', 2]]转换为 object {a: 1, b: 2},这在这里非常有用。
于 2015-03-21T01:32:25.653 回答
0

这是答案(或一种方法),如果有人想知道......

r.expr([{"a":1, "b":2}, {"a":3}, {"c":4}]).do( r.js("(function(input){ 
   var keys=['a','b','c'], output={}; 
   input.forEach(function(e){ 
        for(var p in e){ 
              output[p] = (output[p] || []).concat(e[p]);  
   } }); 
   return output; })"
))
于 2015-03-21T00:53:18.053 回答