Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple key search in CouchDB

Tags:

couchdb

Given the following object structure:

{
   key1: "...",
   key2: "...",
   data: "..."
}

Is there any way to get this object from a CouchDB by quering both key1 and key2 without setting up two different views (one for each key) like:

select * from ... where key1=123 or key2=123

Kind regards, Artjom

edit:

Here is a better description of the problem: The object described above is a serialized game state. A game has exactly one creator user (key1) and his opponent (key2). For a given user I would like to get all games where he is involved (both as creator and opponent).

like image 829
artkoenig Avatar asked May 30 '12 16:05

artkoenig


3 Answers

Emit both keys (or only one if equal):

function(doc) {
  if (doc.hasOwnProperty('key1')) {
    emit(doc.key1, 1);
  }
  if (doc.hasOwnProperty('key2') && doc.key1 !== doc.key2) {
    emit(doc.key2, 1);
  }
}

Query with (properly url-encoded):

?include_docs=true&key=123

or with multiple values:

?include_docs=true&keys=[123,567,...]

UPDATE: updated to query multiple values with a single query.

like image 110
Marcello Nuccio Avatar answered Nov 09 '22 05:11

Marcello Nuccio


You could create a CouchDB view which produces output such as:

["key1", 111],
["key1", 123],
["key2", 111],
["key2", 123],
etc.

It is very simple to write a map view in javascript:

function(doc) {
    emit(["key1", doc["key1"]], null);
    emit(["key2", doc["key2"]], null);
}

When querying, you can query using multiple keys:

{"keys": [["key1", 123], ["key2", 123]]}

You can send that JSON as the data in a POST to the view. Or preferably use an API for your programming language. The results of this query will be each row in the view that matches either key. So, every document which matches on both key1 and key2 will return two rows in the view results.

like image 39
David V Avatar answered Nov 09 '22 06:11

David V


I also was struggling with simular question, how to use

"select * from ... where key1=123 or key2=123". 

The following view would allow you to lookup customer documents by the LastName or FirstName fields:

function(doc) {
  if (doc.Type == "customer") {
      emit(doc.LastName, {FirstName: doc.FirstName, Address: doc.Address});
      emit(doc.FirstName, {LastName: doc.LastName, Address: doc.Address});
  }
}
like image 37
TonyW Avatar answered Nov 09 '22 07:11

TonyW