原文地址: https://www.elastic.co/guide/cn/elasticsearch/guide/current/application-joins.html, 版权归 www.elastic.co 所有
英文版地址: https://www.elastic.co/guide/en/elasticsearch/guide/current/application-joins.html
英文版地址: https://www.elastic.co/guide/en/elasticsearch/guide/current/application-joins.html
请注意:
本书基于 Elasticsearch 2.x 版本,有些内容可能已经过时。
本书基于 Elasticsearch 2.x 版本,有些内容可能已经过时。
应用层联接 (Application-side Joins)edit
我们通过在我们的应用程序中实现联接可以(部分)模拟关系数据库。 例如,比方说我们正在对用户和他们的博客文章进行索引。在关系世界中,我们会这样来操作:
PUT /my_index/user/1 { "name": "John Smith", "email": "john@smith.com", "dob": "1970/10/24" } PUT /my_index/blogpost/2 { "title": "Relationships", "body": "It's complicated...", "user": 1 }
通过用户的 ID 1
可以很容易的找到博客帖子。
GET /my_index/blogpost/_search { "query": { "filtered": { "filter": { "term": { "user": 1 } } } } }
为了找到用户叫做 John 的博客帖子,我们需要运行两次查询: 第一次会查找所有叫做 John 的用户从而获取他们的 ID 集合,接着第二次会将这些 ID 集合放到类似于前面一个例子的查询:
GET /my_index/user/_search { "query": { "match": { "name": "John" } } } GET /my_index/blogpost/_search { "query": { "filtered": { "filter": { "terms": { "user": [1] } } } } }
应用层联接的主要优点是可以对数据进行标准化处理。只能在 user
文档中修改用户的名称。缺点是,为了在搜索时联接文档,必须运行额外的查询。
在这个例子中,只有一个用户匹配我们的第一个查询,但在现实世界中,我们可以很轻易的遇到数以百万计的叫做 John 的用户。 包含所有这些用户的 IDs 会产生一个非常大的查询,这是一个数百万 词项(term) 的查找。
这种方法适用于第一个实体(例如,在这个例子中 user
)只有少量的文档记录的情况,并且最好它们很少改变。这将允许应用程序对结果进行缓存,并避免经常运行第一个查询(查询用户id)。