I am implementing a filter feature for my application and having trouble with writing the view on CouchDB. While in SQL, this would be a statement with multiple join. How to replace multiple join in CouchDB. This article covers single join: http://www.cmlenz.net/archives/2007/10/couchdb-joins. However, it’s not obvious to me how to extend this approach to multiple join.
Imagine my object has a dozen properties and each property can have its individual filter. For simplicity, let’s assume it has only two properties. If we can solve that, we can probably extend it to any number of properties.
My application needs to support a bunch of AND filters. E.g. find all sessions where location in (“Seattle”, “New York”) AND start-epoch >= 1336608413. And I also need to persist filter settings.
In SQL, I have two tables: Session and Filter. Then I have one join per filter condition between Session and Filter table to get all filtered sessions.
Session Table
location start-epoch
Seattle 1336608413
Filter Table
Name Value
location Seattle
location New York
start-epoch 1336608413
Query:
select *
from Session s
where exists (select 1 from Filter f where f.name = 'location' and f.value = s.location)
and exists (select 1 from Filter f on f.name = 'start-epoch' and s.start-epoch >= f2.value)
In CouchDB:
{"type":"session", "location":"Seattle", "start-epoch":1336608413}
Then how to model filter and write the view?
Filter could be something like this:
{"type":"filter", "location":["Seattle", "New York"], "start-epoch":1336608413}
Then how to write the view?
I want to achieve this inside CouchDB. I am hoping to create a view called FilteredSessions and retrieve the filtered session in one http call to Couch. The reason is because I have 5 different clients (iOS, Android, Silverlight, Ruby on Rails and Windows 8) and I don’t want to rewrite the logic 5 times. If I use sqlite, I can create a view called “FilteredView” to achieve that. I hope to write the equivalent in map reduce.
Here is the idea I have. In map function, emit both session and filter documents. Then use the list function to enumerate the map output to read the persisted filters and sessions to do the filtering.