Search code examples
databaseviewcloudantnosql

Retrieve documents from cloudant db if they contain a value in an array property


This is how I currently do it, is there a better (more performant or simpler) way?

Documents in Cloudant db:

1 ..

{
  "_id": "someId",
  "_rev": "someRev",
  "title": "someTitle",
  "parentDirectories": [
    '/', '/base_dir'
  ]
}

2 ..

{
  "_id": "someId2",
  "_rev": "someRev",
  "title": "someTitle2",
  "parentDirectories": [
    '/', '/base_dir'
  ]
}

Currently,I have this view defined in Cloudant and set the include_docs parameter to true so the entire object is returned (this is required) ..

function (doc) {
  if (doc.parentDirectories) {
    for (i = 0; i < doc.parentDirectories.length; i++) {
      emit(doc.parentDirectories[i], {_id: doc._id});
    }
  }
}

And would call the view using ..

/<database>/_design/<design-doc>/_view/my_view?include_docs=true

Using keys parameter set to: ['/'], so view returns the 2 documents above.


Solution

  • Your solution is fine. Creating a index whose keys are the keys from your array is a perfectly good way to retrieve documents that contain a known value. One small iteration is emit null as the value, as you are retrieving the whole document at query-time anyway (with include_docs=true):

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

    You could also emit a subset of your document:

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

    meaning that you could avoid using include_docs=true, for a faster response.