Note that there are some explanatory texts on larger screens.

plurals
  1. POCouchDB view composing JSON objects with embedded arrays from two separated documents
    text
    copied!<p>Lets say I have two types of documents stored in my CouchDB database. First is with property type set to <strong>contact</strong> and second to <strong>phone</strong>. Contact type document have another property called name. Phone type have properties number and contact_id so that it can reference to contact person. This is trivial one to many scenario where one contact can have N phone numbers (I know that they can be embedded in single contact document, but I need to demonstrate one to many relationship with different documents).</p> <p>Raw example data with Scott having 2 phone numbers and Matt having 1 number:</p> <pre><code>{_id: "fc93f785e6bd8c44f14468828b001109", _rev: "1-fdc8d121351b0f5c6d7e288399c7a5b6", type: "phone", number: "123456", contact_id: "fc93f785e6bd8c44f14468828b00099f"} {_id: "fc93f785e6bd8c44f14468828b000f6a", _rev: "1-b2dd90295693dc395019deec7cbf89c7", type: "phone", number: "465789", contact_id: "fc93f785e6bd8c44f14468828b00099f"} {_id: "fc93f785e6bd8c44f14468828b00099f", _rev: "1-bd643a6b0e90c997a42d8c04c5c06af6", type: "contact", name: "Scott"} {_id: "16309fcd03475b9a2924c61d690018e3", _rev: "1-723b7c999111b116c353a4fdab11ddc0", type: "contact", name: "Matt"} {_id: "16309fcd03475b9a2924c61d69000aef", _rev: "3-67193f1bfa8ed21c68e3d35847e9060a", type: "phone", number: "789456", contact_id: "16309fcd03475b9a2924c61d690018e3"} </code></pre> <p>Map function:</p> <pre><code>function(doc) { if (doc.type == "contact") { emit([doc._id, 1], doc); } else if (doc.type == "phone") { emit([doc.contact_id, 0], doc); } } </code></pre> <p>Reduce function:</p> <pre><code>function(keys, values) { var output = {}; for(var elem in values) { if(values[elem].type == "contact") { output = { "ID": values[elem]._id, "Name": values[elem].name, "Type": values[elem].type, "Phones": [] }; } else if (values[elem].type == "phone") { output.Phones.push({ "Number": values[elem].number, "Type": values[elem].type }); } } return output; } </code></pre> <p>group_level is set to 1 because of keys in Map function. Now I can get my contacts with included phones for example like this:</p> <pre><code>http://localhost:5984/testdb2/_design/testview/_view/tv1?group_level=1 </code></pre> <p>Or search for some contact with startkey and endkey like this:</p> <pre><code>http://localhost:5984/testdb2/_design/testview/_view/tv1?group_level=1&amp;startkey=[%22fc93f785e6bd8c44f14468828b00099f%22]&amp;endkey=[%22fc93f785e6bd8c44f14468828b00099f%22,{}] </code></pre> <p>Results look exactly how I want - contacts will have embedded phones according to one to many relationship. And here goes the question: Is this the right way of how to use MapReduce functions in CouchDB? Are there any notable performance issues when using this approach?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload