首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >基于Cloudant/CouchDB链式映射约简的聚合过滤和排序

基于Cloudant/CouchDB链式映射约简的聚合过滤和排序
EN

Stack Overflow用户
提问于 2013-04-03 20:11:19
回答 1查看 2.5K关注 0票数 1

我想过滤一个列表,并根据一个聚合进行排序;这在SQL中是相当简单的,但是我不知道用迭代Map来实现它的最佳方法。我特别使用Cloudant在CouchDB中添加的"dbcopy“,但我认为这种方法可能与其他map/reduce体系结构类似。

伪代码SQL可能如下所示:

代码语言:javascript
运行
复制
SELECT   grouping_field, aggregate(*)
FROM     data
WHERE    #{filter}
GROUP BY grouping_field
ORDER BY aggregate(*), grouping_field
LIMIT    page_size

过滤器可能正在寻找匹配项,也可能在某个范围内进行搜索;例如,field in ('foo', 'bar')field between 37 and 42

例如,考虑电子邮件的数据集;分组字段可能是"List- ID“、"Sender”或"Subject";聚合函数可能是count(*)max(date)min(date);filter子句可能考虑标志、日期范围或邮箱ID。文档可能是这样的:

代码语言:javascript
运行
复制
{
  "id": "foobar", "mailbox": "INBOX", "date": "2013-03-29",
  "sender": "foo@example.com", "subject": "Foo Bar"
}

与同一个发件人一起获得电子邮件的数量是微不足道的:

代码语言:javascript
运行
复制
"map": "function (doc) { emit(doc.sender, null) }",
"reduce": "_count"

Cloudant有一个很好的例子,可以根据地图约简的第二次传递进行排序。。但是当我也想要过滤(例如通过邮箱)时,事情会很快变得混乱。

如果我将过滤器添加到视图键(例如,最终结果看起来类似于{"key": ["INBOX", 1234, "foo@example.com"], "value": null} ),那么在单个筛选值中按计数进行排序就很简单了。但是,使用多个筛选器按计数对数据进行排序需要遍历整个数据集(按键),这在大型数据集上太慢了。

或者,我可以为每个潜在的过滤器选择创建一个索引;例如,最终结果看起来像{"key": [["mbox1", "mbox2"], 1234, "foo@example.com"], "value": null}, (当"mbox1“和"mbox2”都被选中时)或{"key": [["mbox1"], 1234, "foo@example.com"], "value": {...}}, (当只选择"mbox1“时)。这很容易查询,而且速度很快。但是,似乎索引的磁盘大小将呈指数增长(随不同的过滤字段的数量而增加)。而且,对开放式数据(如日期范围)进行过滤似乎是完全站不住脚的。

最后,我可以动态地生成视图,这些视图只在需要的情况下动态地处理所需的过滤器,并在它们不再被使用(以节省磁盘空间)之后将它们删除。这里的缺点是代码复杂性的巨大飞跃,以及每次选择新的过滤器时都要付出很大的前期成本。

有更好的办法吗?

EN

Stack Overflow用户

发布于 2013-04-04 18:24:21

我已经思考了将近一天了,我认为没有比你提议的更好的方法了。你们面临的挑战如下:

1)聚合工作(计数、和等)只能通过物化视图引擎(mapreduce)在CouchDB/Cloudant中完成。

2)虽然group_level API提供了一定的灵活性,可以在查询时指定变量粒度,但对于任意布尔查询,它不够灵活。

3) Cloudant中可以通过基于lucene的_search API进行任意布尔查询。但是,_search API不支持聚合post查询。对您想要做的事情的有限支持只能在lucene中使用faceting,而Cloudant中还不支持这个功能。即使如此,我相信它可能只支持count,而不支持sum或更复杂的聚合。

我认为您面临的最佳选择是使用_search API并使用排序、group_by或group_sort,然后在客户机上进行聚合。需要测试的几个示例URL如下所示:

获取/db/_design/ddoc/_search/indexname?q=name:mike和age:1.2 TO 4.5&sort="age","name“

获取/db/_design/ddoc/_search/indexname?q=name:mike和group_by=“邮箱”和group_sort=“年龄”、“名称”

票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15797112

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档