【发布时间】:2011-11-11 17:51:26
【问题描述】:
我在 rails 和 couchdb 上使用 ruby,但我在 couchdb 中查看问题
在我想要的 sql 中:
select * from user where username = ... or email = ... and status = ...
如何创建这样的视图?
【问题讨论】:
标签: ruby-on-rails couchdb
我在 rails 和 couchdb 上使用 ruby,但我在 couchdb 中查看问题
在我想要的 sql 中:
select * from user where username = ... or email = ... and status = ...
如何创建这样的视图?
【问题讨论】:
标签: ruby-on-rails couchdb
该查询是您数据的联接。 (不,这不是一个实际的 JOIN 声明,但我的意思是,你问了 3 个不同的问题,并在答案中“加入”了结果。)
假设你做了 2 个视图,值是 status,键是这样的:
by_usernameby_email保留地图 (Java)、字典 (Python)、散列 (Perl)、对象 (Javascript) 或任何您的键/值数据结构。您想保留一组匹配的用户,然后添加到其中。
查询每个视图。如果状态是您所需要的,请将用户名添加到您的集合中。完成所有查询后,您就有了完整的答案。
哦不!但这太慢了!事实上,很多时候,解决方案“理论上”很慢,但实际上它们对于需求来说已经足够快了。你有一个 Rails 服务器。它可能具有对 CouchDB 的高速、低延迟 (LAN) 访问。 CouchDB 中的每个查询始终是有效的索引扫描。所以你提出了 3 个请求,bam,bam,bam!客户端通过低速、高延迟的连接(互联网)查询 Rails,它可能不会注意到。
或者,根据您的语言和技能,您可以同时(异步)执行这些查询,并且查询时间基本上会很快。
CouchDB 实际上支持对视图进行一些“或”查询。详情请见CouchDB view options。
您需要一个视图来存储所有信息。我建议使用数组键[status, key_type, key_value]。例如,如果您有两个用户 Alice 和 Bob,则查看键为:
["reading" , "email" , "alice@alice.com"]
["reading" , "username", "alice"]
["sleeping", "email" , "bob@bob.com"]
["sleeping", "username", "bob"]
您将如何查询status = "sleeping" and username = "X" or email = "Y"?
这变成了对视图的多个查询,每个查询都有不同的键:
key=["sleeping", "username", "X"]
key=["sleeping", "email" , "Y']
幸运的是,您可以同时查询多个键。
POST /db/_design/example/_view/state_and_identifiers
Content-Type: application/json
{"keys": [ ["sleeping", "username", "X"]
, ["sleeping", "email" , "Y']
]
}
CouchDB 将在一个响应中返回所有结果。
第二种解决方案非常强大,但是您必须做很多工作才能获得正确的查询。而且这种技术不能总是满足任何 SQL 查询。 SQL 对于提出您能想到的任何问题都更强大。对于 CouchDB,您总是必须先教它要做什么。那很不方便。但结果是,查询保证很快。
考虑到方案2的不便,我个人更喜欢方案1。可以在CouchDB中做一个“join”吗?当然!连接就是这么简单。只需进行多次查询,直到获得所需的数据。如果您的应用程序需要经常“加入”,而使用 CouchDB 又困难又麻烦怎么办?这是一个强有力的信号,表明 CouchDB 可能不适合您的应用程序。
【讨论】:
by_username 和 by_email。是错字还是我遗漏了什么?
a OR b OR c,但实际上是a AND b OR C,并且更正的编辑不完整。主要教训是 (1) 有时,只需查询几次并加入您的应用程序,但 (2) 如果情况失控,看起来您毕竟需要 SQL。