2010-11-21 31 views
2

我使用了Riak存储JSON文档现在排序,我想基于一些属性对它们进行排序,让我们说有一个关键,即如何文档中使用Erlang的地图在了Riak减少

{ “someAttribute”:“whatever”, “order”:1 }

所以我想根据“订单”对文档进行排序。

我目前正在用erlang界面检索riak中的文档。我可以将文档作为字符串取回,但在此之后我不知道该怎么做。我在想这个map函数只是减少了json文档本身,而在reduce函数中,我会检查一下,看看我正在查看的项目是否具有比其余部分更高的“顺序”列表,如果是这样附加到开头,然后返回一个列表:反向。

尽管我的想法如上所述,在几乎整整一天之后,我已经得到了零结果,但我对于erlang接口在riak中很困惑。有人可以提供关于如何编写这个map/reduce函数的见解,或者只是如何解析json文档?

回答

1

据我所知,您无权访问地图中的输入列表。您从Map中将文档发送为1个元素列表。

输入(所有文档处理为{Bucket,Key}) - > Map(处理单个文档) - > Reduce(从Map发出的整个列表)。

地图在许多节点上按每个doc执行,而Reduce在所谓的协调节点(调用查询的节点)上完成一次。

解决方案:

  1. 定义输入(作为列表或桶)
  2. 检索值在地图和发射整个文件或{ID,Val_to_sort_by)
  3. 排序中降低(使用规则列表:keysort )
+0

我有点困惑,在riak/java脚本的例子中,他们可以做到这一点。 函数(value,keyData,arg)var data = Riak。mapValuesJson(值)[0]; if(data.High && data.High> 600.00) return [value.key]; else return []; } 所以他们得到他们在var数据中看到的任何东西。 然后他们做一个数据。就好像它是一个属性。我想这取决于 他们甚至如何将文档放在首位。我不能为订单做同样的事吗? (不是您所说的“输入”部分) – user436605 2010-11-22 15:58:34

+0

在给出的示例中,该语句用于过滤映射阶段中的数据。排序不能在地图阶段完成,因为它一次只能处理一条记录。 – 2012-12-14 12:56:16

0

这不是地图缩小解决方案,但您应该检出Riak Search

+0

你能解释一下riak搜索会如何帮助我吗?它看起来像是'更有效的机制来标记项目,以便我可以稍后检索它们。他们的erlang API示例是 搜索:搜索(<<"books">>,<<作者:joyce >> >>)。 所以我可以找到搜索桶书籍,说一个JSON文档与一个关键“作者”和一个值“joyce”。我的问题是我需要根据特定的属性进行排序。如何将riak搜索做到这一点? – user436605 2010-11-22 16:18:38

0

所以我“解决了”使用javascript的问题,仍然无法使用erlang来完成。 这里是我的查询

{"inputs":"test", 
"query":[{"map":{"language":"javascript", 
        "source":"function(value, keyData, arg){ var data = Riak.mapValuesJson(value)[0]; var obj = {}; obj[data.order] = data; return [ obj ];}"}}, 
     {"reduce":{"language":"javascript", 
        "source":"function(values, arg){ return [ values.reduce(function(acc, item){ for(var order in item){ acc[order] = item[order]; } return acc; }) ];}", 
        "keep":true}} 
     ] 
} 

所以在map阶段,我要做的就是创建一个新的数组,OBJ,关键的顺序和值数据本身。所以在视觉上,该obj是这样

{"1":{"firstName":"John","order":1} 
在简化阶段

,我只是把它在蓄压器,所以基本上这就是那种,如果你仔细想想,因为当你做,一切都会为了你而放置。所以我把2个JSON文件进行测试,一个是上面的ohter只是姓:比利,为了2,这里是我的查询结果上述

[{"1":{"firstName":"John","order":1},"2":{"firstName":"Billie","order":2}}] 

所以它的作品! 。但我仍然需要在ERLANG中做到这一点,有什么见解?

+0

您正在做的是从自我排序结构的地图部分返回 - 但仅从JS VM的角度来看。在Erlang中,我没有看到相同的结果(你需要有整个结构并添加元素以保持排序)。也许产生一个进程并在排序的ETS集中保存一个值? – user425720 2010-11-23 10:50:45

+0

(Spawn需要避免vnodes上的死锁) – user425720 2010-11-23 10:56:46

+0

更多细节:在调用M/R之前创建公共排序的ETS表。将名称/编号传递给地图。在每个映射表中保存值。在减少,只是检索数据。甚至可以跳过减少 - 你可以使用表ID来稍后获取数据。从Erlang的角度来看,这不是最好的解决方案,因为它提供了全局状态(ETS),但它可能很方便。 – user425720 2010-11-23 11:11:32