Couchdb join two documents using key
Asked Answered
S

2

5

I have two documents one with tree structure and the other one relation to the first doc. Im trying to join these two doc`s by fk and pk. I couldnt get the actual results and it displays all null values.

First doc

{
   "name": "one",
   "root": {
            "level1" : {
                       "level2" : {
                                 "level3" : {
                                           "itemone": "Randomkey1",
                                           "itemtwo": "Randomkey2
                                          }
                                }
                     }
         },
   "type": "firstdoc"
}

Second doc

{
    "name"  : "two",
    "mapBy" : "Randomkey1",
    "type"  : "senconddoc
}

I`ve written a map function, which lists all the keys given a level 1 or 2 or 3 . Now I want o join this first doc and second doc using the key. Ive tried two ways (first: Im getting all (Root, Randomkey), (docName, Randomkey1) but it doesnt do any join. Im looking for a result like (Root, docName)

Could someone assist in fixing this

map

function(doc) {
   if (doc.type === 'firstdoc' || doc.type === 'seconddoc' ) {
      var rootObj = doc.Root;
      for (var level1 in rootObj) {

         var level2Obj = doc.Root[level1];

         for (var level2 in level2Obj) {

           var keys = new Array();
            var level3Obj = level2Obj[level2];

            for (var i in level3Obj) {

                var itemObj = level3Obj[i];

                for (var i in itemObj) {
                    keys.push(itemObj[i]);

                    emit(doc.name, [itemObj[i], 0]);

                     var firstDocName = doc.name;

                    //This is gives null values
                    if (doc.Type === 'senconddoc' && doc.mapBy === itemObj[i]) {

                         emit(firstDocName , doc);
                    }
                }
            }



        }


    }
}

//This just lists keys to me
if (doc.type === 'senconddoc') {

    emit([doc.mapBy, 1] , doc);
}
}
Sphygmic answered 31/1, 2015 at 4:57 Comment(0)
S
9

To simulate joins you have to output a doc with an _id in it, the value of the _id needs to point to an actual _id of a document. Then you can make use of include_docs=true to pull in the related documents. Example with many-to-many here: http://danielwertheim.se/couchdb-many-to-many-relations/

If this is not applicable, you can make a two step manual join by first returning custom keys. Then make a second query against the all documents view, with multiple keys specified.

Solomonsolon answered 31/1, 2015 at 8:54 Comment(3)
Daniel, I’m trying to understand how the second alternative would work. Do you mean write two views, then query one, and use it’s response to tailor the query to the other in the client?Talion
@AhmedFasih nope, one view to return the keys that maps to the id's of the docs you want, then issue a second query against the all_docs view (system view) matching those Ids. But I would stay away from joins if I could in Couch (not really using Couch anymore BTW)Solomonsolon
@Solomonsolon what do you use then instead?Importance
M
1

It is much late but For such kind of tree structure, documents should be kept separately such as

{
  id="firstDoc",
  type="rootLevel"
}
{
  id="secondDoc",
  type="firstLevel"
  parent="firstDoc"
}
{
  id="thirdDoc",
  type="firstLevel",
  parent="firstDoc"
}

Now different levels can be joined using the Map Reduce function, Make sure that you will use it in proper way, Also use Logging so that you will be able to know in which sequence map/reduce function are being called by CouchDB.

Further, map Function should only be used for emitting the required document suppose if you want to to emit your level3 then in emit's value part, root.level1.level2.level3 should be there.

For more detail about the join you can refer

CouchDB Join using Views (map/reduce)

Moyers answered 3/6, 2019 at 11:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.