views:

1081

answers:

4

How are multiple range queries implemented in CouchDB? For a single range condition, startkey and endkey combination works fine, but the same thing is not working with a multiple range condition.

My View function is like this:

"function(doc){
       if ((doc['couchrest-type'] == 'Item') 
    && doc['loan_name']&& doc['loan_period']&&    
                      doc['loan_amount']) 
     {  emit([doc['template_id'],
          doc['loan_name'],doc['loan_period'],
           doc['loan_amount']],null);}}"

I need to get the whole docs with loan_period > 5 and loan_amount > 30000. My startkey and endkey parameters are like this:

params = {:startkey =>["7446567e45dc5155353736cb3d6041c0",nil,5,30000],
  :endkey=>["7446567e45dc5155353736cb3d6041c0",{},{},{}],:include_docs => true}

Here, I am not getting the desired result. I think my startkey and endkey params are wrong. Can anyone help me?

A: 

Your emit statement looks a little strange to me. The purpose of emit is to produce a key (i.e. an index) and then the document's values that you are interested in.

for example:

emit( doc.index, [doc.name, doc.address, ....] );

You are generating an array for the index and no data for the view.

Also, Couchdb doesn't provide for an intersection of views as it doesn't fit the map/reduce paradigm very well. So your needs boil down to trying to address the following:

Can I produce a unique index which I can then extract a particular range from? (using startkey & endkey)

timbo
+2  A: 

A CouchDB view is an ordered list of entries. Queries on a view return a contiguous slice of that list. As such, it's not possible to apply two inequality conditions.

Assuming that your loan_period is a discrete variable, this case would probably be best solved by emit'ing the loan_period first and then issuing one query for each period.

An alternative solution would be to use couchdb-lucene.

Paul J. Davis
A: 

Actually CouchDB allows views to have complex keys which are arrays of values as given in the question:

[template_id, loan_name, loan_period, loan_amount]

Have you tried

params = {:startkey =>["7446567e45dc5155353736cb3d6041c0",nil,5,30000],
  :endkey=>["7446567e45dc5155353736cb3d6041c0",{}],:include_docs => true}

or perhaps

params = {:startkey =>["7446567e45dc5155353736cb3d6041c0","\u0000",5,30000],
  :endkey=>["7446567e45dc5155353736cb3d6041c0","\u9999",{}],:include_docs => true}
Dokie
A: 

You're using arrays as your keys. Couchdb will compare arrays by comparing each array element in increasing order until two element are not equal.

E.g. to compare [1,'a',5] and [1,'c',0] it will compare 1 whith 1, then 'a' with 'c' and will decide that [1,'a',5] is less than [1,'a',0]

This explains why your range key query fails:

["7446567e45dc5155353736cb3d6041c0",nil,5,30000] is greater ["7446567e45dc5155353736cb3d6041c0",nil,5,90000]

ordnungswidrig