Search code examples
jsonibm-cloudcloudant

cloudant view for nested json documents


I am trying to create a view in Cloudant DB which will pick up all the JSON documents based on the value of one field (SAVE_TYPE_SUBMIT). My problem is that, the JSON document contains nested fields. Please take a look at the sample document below.

{
  "_id ": "70f79cc9309fd8b2bcca90efd871f993 ",
  "_rev": "1-18fe726fc3d99f50a945ab30c9ffeb4b",
  "NAME": "qqq",
  "EMAIL": "qqq",
  "TITLE": "qq",
  "DATE_OF_REPORT": "2017/08/17",
  "PUBLIC_OFFICIALS_CONTACTED": [{
      "NAME_PUBLIC_OFFICIAL": "qq"
    },
    {
      "TITLE_PUBLIC_OFFICIAL": "qq"
    }
  ],
  "MANAGER": "qq",
  "SAVE_TYPE_SUBMIT": "Submit"
}

The view created is :

function(doc) { 
  if (("SAVE_TYPE_SUBMIT" in doc) && (doc.SAVE_TYPE_SUBMIT == "Submit")) { 
    emit (doc.LAST_UPDATE_BY, [doc.NAME, doc.EMAIL, doc.TITLE, doc.DATE_OF_REPORT, doc.PUBLIC_OFFICIALS_CONTACTED, doc.MANAGER]);
  }
}

When I try to fetch the data from this view into my application, I do not get the value of the nested fields, i.e. NAME_PUBLIC_OFFICIAL and TITLE_PUBLIC_OFFICIAL. I see those fields as [object,object]. Please note that PUBLIC_OFFICIALS_CONTACTED can contain multiple Name and Title fields.

Please help understand how the view needs to be customized to get the value of the nested fields. I am having a hard time with this and any guidance or material will be highly appreciated!


Solution

  • Create a map function of this form:

    function(doc) { 
      if (("SAVE_TYPE_SUBMIT" in doc) && (doc.SAVE_TYPE_SUBMIT == "Submit")) { 
        emit(doc.LAST_UPDATE_BY, { name:doc.NAME, email: doc.EMAIL, title: doc.TITLE, date: doc.DATE_OF_REPORT, officials: doc.PUBLIC_OFFICIALS_CONTACTED, manager: doc.MANAGER});
      }
    }
    

    This is very similar to your map function except that it emits a value which is an Object instead of an array. This object can represent a subset to the original document.

    If you need ALL the fields from the original document, then you could modify the function to:

    function(doc) { 
      if (("SAVE_TYPE_SUBMIT" in doc) && (doc.SAVE_TYPE_SUBMIT == "Submit")) { 
        emit(doc.LAST_UPDATE_BY, null);
      }
    }
    

    and add ?include_docs=true when querying the view to add the original document bodies to the response.