模拟联接如何在Couchbase中运行?

时间:2014-01-12 15:46:58

标签: couchbase

我有一个文件依赖于其他文件。第一:

{
  "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"
    }
}

在这里你可以看到doc.buyer.person依赖于这样的另一个文件:

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

如何从这两份文件中获取买家的姓名?我的意思是doc.buyer.person与第二个文档的id相关联。它是连接,从文档中不清楚。 http://docs.couchbase.com/couchbase-manual-2.0/#solutions-for-simulating-joins

2 个答案:

答案 0 :(得分:5)

首先,请允许我指出您引用的文档部分的第一句话(我添加了重点):

  

数据之间的连接,即使正在检查的文档是   包含在同一个桶中,不可能直接在其中   查看系统

所以,你的问题的快速回答是你有很多选择。以下是其中一些:

  1. 假设您只需要一小部分人的名字。创建一个视图,将PersonId作为键输出,Name作为值输出,然后在每次需要时查询视图中的特定名称。
  2. 假设你需要很多人参加很多拍卖会。从#1下载基本索引的全部内容,并使用linq执行连接。
  3. 假设您需要此人的许多属性,而不仅仅是名称。下载每个拍卖项目的“个人”文档。
  4. 假设您需要来自Auction和People的一小部分。索引您需要的每个字段,包括一个类型字段,并在Person的键下发出所有字段。您将能够查询属于该人的所有项目的视图。
  5. 您在问题中链接的示例中使用了最后一种方法。为了提高性能,有必要根据您的使用场景定制方法。

答案 1 :(得分:2)

另一种解决方案是在自定义reduce函数中合并数据。

// 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;
}

然后你可以用" key"查询一个用户。或多个用户使用"键"。

在我不知道这种方法的性能问题之后。