How does Simulating Joins works in Couchbase?

混江龙づ霸主 提交于 2019-12-19 08:28:09

问题


I have documents one is dependent to other. first:

{
  "doctype": "closed_auctions",
  "seller": {
    "person": "person11304"
  },
  "buyer": {
    "person": "person0"
  },
  "itemref": {
    "item": "item1"
  },
  "price": 50.03,
  "date": "11/17/2001",
  "quantity": 1,
  "type": "Featured",
  "annotation": {
    "author": {
      "person": "person8597"
    }
}

here you can see doc.buyer.person is dependent to another documents like this:

{
  "doctype": "people",
  "id": "person0",
  "name": "Kasidit Treweek",
  "profile": {
    "income": 20186.59,
    "interest": [
      {
        "category": "category251"
      }
    ],
    "education": "Graduate School",
    "business": "No"
  },
  "watch": [
    {
      "open_auction": "open_auction8747"
    }
  ]
}

How can I get buyer's name from these two documents? I means doc.buyer.person is connected with second document's id. It is join and from documentation it's not clear. http://docs.couchbase.com/couchbase-manual-2.0/#solutions-for-simulating-joins


回答1:


Well, first off, let me point out that the very first sentence of the documentation section that you referenced says (I added the emphasis):

Joins between data, even when the documents being examined are contained within the same bucket, are not possible directly within the view system.

So, the quick answer to your question is that you have lots of options. Here are a few of them:

  1. Assume you need only the name for a rather small subset of people. Create a view that outputs the PersonId as key and Name as value, then query the view for a specific name each time you need it.
  2. Assume you need many people joined to many auctions. Download the full contents of the basic index from #1 and execute the join using linq.
  3. Assume you need many properties of the person, not just the name. Download the Person document for each auction item.
  4. Assume you need a small subset from both Auction and People. Index the fields from each that you need, include a type field, and emit all of them under the key of the Person. You will be able to query the view for all items belonging to the person.

The last approach was used in the example you linked to in your question. For performance, it will be necessary to tailor the approach to your usage scenario.




回答2:


An other solution consist to merge datas in a custom reduce function.

// view
function (doc, meta) {
  if (doc.doctype === "people") {
     emit(doc.id, doc);
  }
  if (doc.doctype === "closed_auctions") {
     emit(doc.buyer.person, doc);
  }
}

// custom reduce
function (keys, values, rereduce) {
   var peoples = values.filter(function (doc) {
       return doc.doctype === "people";
   });
   for (var key in peoples) {
      var people = peoples[key];
      people.closed_auctions = (function (peopleId) {
          return values.filter(function (doc) {
             return doc.doctype === "closed_auctions" && doc.buyer.person === peopleId;
          });
      })(people.id);
   }
   return peoples;
}

And then you can query one user with "key" or multiple users with "keys".

After I don't know what the performances issues are with this method.



来源:https://stackoverflow.com/questions/21076688/how-does-simulating-joins-works-in-couchbase

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!