janmonschke / backbone-couchdb

A couchdb connector for backbone with support for real time changes.

Home Page:http://janmonschke.com/projects/backbone-couchdb.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Accept doc.key instead of doc.value for group-by/distinct mapreduce views

jasonm opened this issue · comments

A little context: I have an application with readers and scans, but the only documents I record into Couch are the scans, which contain a reader_description field.

I'd like to have a read-only collection of Readers, containing the distinct set of reader_description fields from the scans collection, so I have a map-reduce view function to emit distinct reader docs:

# to be used with group=true
distinctReadersFromScans:
  map: (doc) ->
    if doc.collection == 'scan'
      readerDoc = { name: doc.reader_description }
      emit(readerDoc, doc)
  reduce: (keys, values) ->
    null

I found this approach on http://stackoverflow.com/questions/2534376/how-do-i-do-the-sql-equivalent-of-distinct-in-couchdb

However, the HTTP response is formatted like this:

{"rows":[
{"key":{"name":"Fake Reader Foxtrot"},"value":null},
{"key":{"name":"Fake Reader Waltz"},"value":null},
{"key":{"name":"Alpha hosting USB Reader Blueberry"},"value":null},
{"key":{"name":"Alpha hosting USB Reader Foxtrot"},"value":null},
{"key":{"name":"Alpha hosting USB Reader Waltz"},"value":null},
{"key":{"name":"Alpha hosting USB Reader Waltz Pro"},"value":null}
]}

and when backbone-couchdb's con.read_connection is called, only the value is pushed into the collection:

if doc.value then _temp.push doc.value else _temp.push doc.doc

(From backbone-couchdb.coffee#L94)

which means that my models are populated will null, instead of attr objects like { name: 'Fake Reader Foxtrot' }.

So, I patched the function to handle a null value and emit the key instead:

# JPM: handle group-by mapreduces
if _.isEqual(['key', 'value'], _.keys(doc)) && doc.value == null
  _temp.push doc.key
else
  if doc.value then _temp.push doc.value else _temp.push doc.doc

I'm pretty new to CouchDB and its idioms. Am I doing this right? Is this patch something that others would find helpful? Does it conflict with some other convention in Couch?

Thanks!