如何在couchdb视图中使用OR

Hai*_*ina 4 couchdb ruby-on-rails

我在rails和couchdb上使用ruby,但我在couchdb中有问题视图

在我想要的SQL:

select*from user where username = ...或email = ... and status = ...

我该如何创建这样的视图?

Jas*_*ith 12

该查询是您的数据的连接.(不,这不是一个实际的JOIN陈述,但我的意思是,你要问3个不同的问题并在答案中"加入"结果.)

解决方案1:只需多次查询.

假设您创建了2个视图,则值为,status并且键如下所示:

  • by_username
  • by_email

保留地图(Java),或dict(Python),哈希(Perl),对象(Javascript)或任何您的键/值数据结构.您希望保留一组匹配的用户,并添加到该用户.

查询每个视图.如果状态是您所需要的,请将用户名添加到您的集合中.完成所有查询后,您将获得完整的答案.

不好了!但那太慢了!实际上,通常情况下,解决方案"理论上"很慢,但实际上它们对于要求来说速度很快.你有一个Rails服务器.它可能具有对CouchDB的高速,低延迟(LAN)访问.CouchDB中的每个查询始终是一个有效的索引扫描.所以你提出3个请求,bam,bam,bam!客户端通过低速,高延迟的连接(Internet)查询Rails,它可能不会注意到.

或者,根据您的语言和技能,您可以同时(异步)执行这些查询,并且查询时间基本上会很快.

解决方案2:秘密多键查询

CouchDB实际上支持对视图的一些"OR"查询.有关详细信息,请参阅CouchDB视图选项.

您需要一个视图来存储所有信息.我建议使用数组键[status, key_type, key_value].例如,如果您有两个用户,Alice和Bob,则视图键将是:

["reading" , "email"   , "alice@alice.com"]
["reading" , "username", "alice"]
["sleeping", "email"   , "bob@bob.com"]
["sleeping", "username", "bob"]
Run Code Online (Sandbox Code Playgroud)

你会如何查询status = "sleeping" and username = "X" or email = "Y"

这将成为视图的多个查询,每个查询都有不同的键:

key=["sleeping", "username", "X"]
key=["sleeping", "email"   , "Y']
Run Code Online (Sandbox Code Playgroud)

幸运的是,您可以同时查询多个密钥.

POST /db/_design/example/_view/state_and_identifiers
Content-Type: application/json

{"keys": [ ["sleeping", "username", "X"]
         , ["sleeping", "email"   , "Y']
         ]
}
Run Code Online (Sandbox Code Playgroud)

CouchDB将在一个响应中返回所有结果.

摘要

第二种解决方案非常强大,但是您必须做很多工作才能获得正确的查询.而且这种技术并不总能满足任何 SQL查询.SQL可以更好地提出您可以想到的任何问题.对于CouchDB,您总是必须先教它做什么.这很不方便.但结果是,查询保证很快.

考虑到解决方案2的不便,我个人更喜欢解决方案1.你能在CouchDB中"加入"吗?当然!联接非常简单.只需进行多次查询,直到获得所需的数据.如果您的应用程序需要经常"加入",并且使用CouchDB很困难且有问题,该怎么办?这是一个强有力的信号,表明CouchDB可能不适合您的应用程序.