CouchDb 在一个视图中过滤和排序

CouchDb filter and sort in one view

我是 CouchDb 的新手。 我必须按日期过滤记录(日期必须介于两个值之间)并按名称或日期等对数据进行排序(这取决于用户在 table 中的选择)。 在 MySQL 中看起来像

SELECT * FROM table WHERE date > "2015-01-01" AND date < "2015-08-01" ORDER BY name/date/email ASC/DESC

我不知道是否可以使用一个视图来解决所有这些问题。 这是我的地图示例:

function(doc) {
    emit(
        [doc.date, doc.name, doc.email],
        {
            email:doc.email,
            name:doc.name,
            date:doc.date,
        }
    );
}

我尝试使用 startkey 和 endkey 过滤数据,但我不确定如何以这种方式对数据进行排序:

startkey=["2015-01-01"]&endkey=["2015-08-01"]

我可以使用一个视图吗?或者我必须根据我当前的订单字段创建一些带有键顺序的视图:[doc.date、doc.name、doc.email]、[doc.name、doc.date、 doc.email] 等等?

感谢您的帮助!

您可以通过两种方式使用列表函数:

1.) Couch-View 按日期排序,您按 e-amil 排序 => 但请。请注意,您必须将所有项目都存储在内存中才能通过电子邮件进行排序(即,您只能在结果集较小时执行此操作)

2.) Couch-View 是通过电子邮件订购的,列表功能会删除所有超出日期范围的内容(你只能在整个列表很小的时候这样做——所以这个很可能是坏的)

可能 #1 可以帮助你

正如 Sebastian 所说,您需要在 Couch 中使用列表函数来执行此操作。

如果你仔细想想,这就是 MySQL 正在做的事情。它的查询优化器会在你的 table 中选择一个索引,它会从该索引扫描一个范围,将它需要的内容加载到内存中,然后执行查询逻辑。

在 Couch 中,视图是您的 B 树索引,列表函数可以实现您需要的任何逻辑。可以用来吐出HTML而不是JSON,但是也可以用来filter/sort你view的输出,最后还是吐出JSON .它可能无法很好地扩展到数百万文档,但 MySQL 也可能不会。

所以你的选择就是塞巴斯蒂安强调的那些:

  1. 视图按日期排序,查询选择日期范围,列表函数将所有内容加载到内存中并按 email/etc 排序。

  2. 浏览量按email/etc排序,列表函数过滤掉日期范围外的所有内容。

你选择哪一个取决于你的数据和架构。

使用选项 1,您可以完全跳过列表功能:一次从视图中获取所有必要的数据(使用 include_docs),并对客户端进行排序。 这就是您通常使用 Couch 的方式。

如果您需要在服务器端完成此操作,则需要列表函数将每个匹配的文档加载到一个数组中,然后对其进行排序并 JSON 对其进行序列化。如果有太多匹配的文档,它们甚至无法放入内存或需要很长时间才能排序,这显然会分崩离析。

选项 2 扫描预先订购的文件,只发送与日期匹配的文件。做对了这可以避免将所有内容加载到内存中。 OTOH 它可能会扫描太多文档,破坏您的磁盘 IO。

如果日期范围是"very discriminating"(通过测试的文档很少)选项1效果最好;否则(大多数文档通过)选项 2 可能更好。请记住,在从磁盘加载无用文档所需的时间(选项 2)中,您可以对内存中的数十个文档进行排序,只要它们适合内存(选项 1)。另外,索引越多,使用的磁盘space越多,写入越慢。