How to use OR in couchdb view

I use ruby ​​on rails and couchdb, but I have a problem view in couchdb

in sql I want:

select * from the user, where username = ... or email = ... and status = ...

How to create such a view?

+4
source share
1 answer

This request is a combination of your data. (No, this is not the actual JOIN operator, but I mean that you ask 3 different questions and “attach” the results in the answer.)

Solution 1: just run the query a few times.

Suppose you create 2 views, the value is status , and the keys look like this:

  • by_username
  • by_email

Store a map (Java) or dict (Python), a hash (Perl), an object (Javascript), or any other data structure of your key / value. You want to save the set of relevant users and add to it.

Request every submission. If status is what you need, add usernames to your set. When all requests are completed, you have a complete answer.

Oh no! But it is so slow! In fact, very often decisions are slow “theoretically,” but in fact they are fast enough to meet the requirements. You have a Rails server. It probably has high speed, low latency (LAN) access to CouchDB. Every query in CouchDB is always an efficient index scan. So you make 3 requests, bam, bam, bam! The client requests Rails over a low speed, high latency (Internet) connection, it probably won't notice.

Alternatively, depending on your language and skills, you can execute these requests at the same time (asynchronously), and the request time will be mostly fast.

Solution 2: secret request with multiple keys

CouchDB actually supports some "OR" view requests. See CouchDB Viewing Options for more information.

Storage of all information requires one presentation. I suggest array keys, [status, key_type, key_value] . For example, if you have two users, Alice and Bob, the keys are of the form:

 ["reading" , "email" , " alice@alice.com "] ["reading" , "username", "alice"] ["sleeping", "email" , " bob@bob.com "] ["sleeping", "username", "bob"] 

How would you request for status = "sleeping" and username = "X" or email = "Y" ?

This becomes a few view requests, each with a different key:

 key=["sleeping", "username", "X"] key=["sleeping", "email" , "Y'] 

Fortunately, you can request multiple keys at once.

 POST /db/_design/example/_view/state_and_identifiers Content-Type: application/json {"keys": [ ["sleeping", "username", "X"] , ["sleeping", "email" , "Y'] ] } 

CouchDB will return all results in one answer.

Summary

The second solution is very powerful, however you have to do a lot of work to get the right request. And this method cannot always satisfy any SQL query. SQL is more powerful to ask any question you may think about. For CouchDB, you always need to learn what to do first. It is not comfortable. But the result is guaranteed that requests will be fast.

Given the inconvenience of solution 2, I personally prefer solution 1. Can you make a “connection” in CouchDB? Sure! Pools are so simple. Just do a few queries until you get the data you need. What if your application needs to "join" very often, and using CouchDB is difficult and inefficient? This is a powerful sign that CouchDB is not suitable for your application.

+12
source

All Articles