Question

Let's assume that I have a list of 239800 documents like the following:

{
    name: somename,
    data:{age:someage, income:somevalue, height:someheight, dumplings_consumed:somenumber}
}

I know that I can index the doc by doc.data.age, doc.data.income, height, dumplings_consumed and get list of the doc that after giving a range for each parameters but how can I get a result for query like following:

List of the docs where age is between 25 and 30, income is less than $10 and height is more than 7ft?

Is there a way to get multiple indexes working?

Was it helpful?

Solution

Assuming all three of your example query parameters need to remain dynamic, you would not be able to do such a join with a single CouchDB query. The simplest strategy would be to emit an index that lets you narrow down the "biggest" aspect/dimension of your data, and then filter the rest out in your app's code or a _list function.

Now, for filtering on two aspects of numeric data, GeoCouch could potentially be used — it provides a generic 2-dimensional index, not just limited to latitude and longitude! So you would emit points that contain (say) "age" and "income" mapped to x and y. You'd then query a bbox with first two "between" parameters, and then you'd only have to filter out height on the app side.

OTHER TIPS

Let's have a look at:

http://guide.couchdb.org/draft/views.html

You can search with any expression you want (javascript code) and index documents with it.

For example, by means of Futon, you can create a test database and add the two following documents based on your question:

{ "_id": "36fef0472fb7eec035c87e4f4b0381bf", "_rev": "12-4ef9014a3670a7e6acd58ad92d26fc1e", "data": { "age": 6, "income": 10, "height": 20, "dumplings_consumed": 5 }, "name": "joe" }

{ "_id": "36fef0472fb7eec035c87e4f4b038ffa", "_rev": "8-f0a0a51b830bf3d4bc3ec5697440792f", "name": "mike", "data": { "age": 27, "income": 9, "height": 78, "dumplings_consumed": 256 } }

You just have to go to your database still with Futon and create a temporary view with the following Map function:

function(doc) { var age, income, height; if (doc.name && doc.data && doc.data.age && doc.data.income && doc.data.height) { if ( doc.data.age > 25 && doc.data.age < 30 && doc.data.income < 10 && doc.data.height > 7) { emit(doc.name, doc.data); } } }

Just run and you get the result.

With a permanent view, first time the request is executed, the internal B-tree is built and it takes time. Further executions should be very fast even if documents are added to the database (as long as their number is a fraction of the totality)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top