Skip to content

Instantly share code, notes, and snippets.

@garethbowen
Last active August 29, 2015 14:22
Show Gist options
  • Select an option

  • Save garethbowen/c65413a7907328433f6c to your computer and use it in GitHub Desktop.

Select an option

Save garethbowen/c65413a7907328433f6c to your computer and use it in GitHub Desktop.
Medic Mobile remove lucene dependency

The problem

Lucene is used primarily for filtering reports and contacts so you wouldn't be able to search without it. We used lucene to

  • allow for multiple filters to be applied which couchdb views cannot do, and
  • allow for complex freetext filters

We want to use pouchdb for the mobile app for local and offline storage but pouchdb doesn't work with lucene. Ideally both webapp and mobile app would use the same solution for consistency and code reuse.

Solution

Fall back to using native couch views. Create one view for each filter with the district (for permissions), then the field to be filtered by. The reported_date should be emitted as the value so we can find the latest n results.

When filtering with only one filter set query the view with include_docs=true and limit=50 and show the results.

When filtering with more than one filter set make one request per selected filter in parallel with include_docs=false. Then find the first 50 records that are in all result sets and do a bulk get and show the results.

What about freetext?

Create a couchdb view which emits the doc with each of the fields then query that using the above rules. We could even output the field name, eg: errors:0 if we wanted to get some of the lucene functionality back. I doubt many end users will use the advanced lucene functionality and advanced users (ie: developers) can get access to the db anyway so I don't think we're losing much.

What about multiselect?

For multiselect use the keys parameter, eg: keys=[[null, "P"], [null, "R"]] would get all P and R registrations for the administrator. For large multiselects like facility we would have to be careful to not make the request stupidly large.

Pagination?

Do the same as above but grab the IDs from 50-100 then bulk get those.

Analytics?

ANC Analytics currently uses lucene but won't be included in the mobile app. However, we should convert ANC Analytics to use the same views as above so we can remove lucene and java from the OS.

Examples

No filter

The default view is to show all records the user is allowed to see. Have a view key which has the districtId and reported_date. Request by startkey and endkey of districtId, in descending order, limited by the page, and including docs.

One filter

A user selects form of "P" or "R". Have a view key which has the districtId and formCode with the reported_date as a value. Request by keys [[districtId, "P"],[districtId, "R"]], without docs. Sort descending by value, pick the most recent page, and request bulkDocs.

Multiple filters

A user selects form of "P" and date of "in the last month". As above, request the "P" forms. In parallel, request the view in the "No filter" example with startkey and endkey of districtId and dates, without docs. Find the intersection of the docs that are returned by both requests. Sort the intersection by value, pick the most recent page, and request bulkDocs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment