Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

couchdb view that searches an array field for values passed in as a key array

Tags:

couchdb

views

I have some documents in couchdb that have fields that are arrays of id's for different associated documents:

{
  associatedAssets: ["4c67f6241f4a0efb7dc2abc24a004dfe",  "270fd4508a1222a1e2a27cbe7f002d9z"]
}

I would like to write a view that will let me pass in a key that is itself an array of ids, and then return documents whose associatedAssets fields contain one or more of the ids passed in via the key array e.g.

$.ajax({
  url: "/db/_design/design_doc/_view/summaryByAssociatedAssets",
  type: "post",
  data: JSON.stringify({keys: ["4c67f6241f4a0efb7dc2abc24a004dfe", "6c67f6241f4a0efb7dc2abc24a004dfd"]}),
  dataType: "json",
    contentType: "application/json",
})
.done(function(resp){
  console.log(resp[0]);
});

would return documents whose associatedAssets array contains one or more of the keys "4c67f6241f4a0efb7dc2abc24a004dfe", "6c67f6241f4a0efb7dc2abc24a004dfd".

I can't access the keys in my view, so I'm not sure if I can do this? Is there a better way to accomplish this?

Thanks!

like image 338
Troy Avatar asked Jun 23 '12 05:06

Troy


1 Answers

Your view just needs to generate an output row per associatedAssets element, something like this:

function(doc) {
  if( doc.associatedAssets ) {
    for( var i=0, l=doc.associatedAssets.length; i<l; i++) {
      emit( doc.associatedAssets[i], doc );
    }
  }
}

Then you'd need to adjust your call so it ends up passing that keys array as a query string parameter, which will return only the rows from the view that match keys in that array.

A total aside - assuming a recent CouchDB version, the best practices would be to replace doc in your emit with { _id: doc._id } and then use include_docs=true in your query so your view index doesn't get filled up (unnecessarily) with full documents.

like image 137
smathy Avatar answered Nov 07 '22 07:11

smathy