[转]Cross-type joins in Elasticsearch
Cross-type joins in Elasticsearch
http://rore.im/posts/elasticsearch-joins
December 31, 2014
When modeling data in Elasticsearch, a common question is how to design the data to capture relationships between entities, to allow at least some level of “joins”.
Elasticsearch has a good guide about data modeling. One of the options provided for expressing relationships is the parent-child model.
A parent-child relationship in Elasticsearch is a way to express a one-to-many relationship (a parent with many children). The parent and child are separate Elasticsearch types, bounded only by specifying the parent type on the child mapping, and by giving the parent ID for every child index operation (this is used for routing the child to the shard of the parent).
It’s a useful model when a parent has many children and when the child update pattern is different from that of the parent. (Since every child is a separate document, updating the child does not require re-indexing the parent).
But this model also provides an interesting (if limited) way to capture relationships between sibling types.
Lets consider the following data:

Bill has two children - Adam and Eve, and a Dog (Apple).
Bob has no children or pets (ah, freedom!).
Mary has a little newborn child called Lamb.
Jane has a boy named Xander, a cat (Buffy) and a dog (Willow).
Lets create this data in Elasticsearch.
We will have a parent type - “person”, and two child types - “children” and “pets”.
First we’ll create the mapping for the child types.
#!/bin/bash
export ELASTICSEARCH_ENDPOINT="http://localhost:9200"
# Create indexes
curl -XPUT "$ELASTICSEARCH_ENDPOINT/es-joins" -d '{
"mappings": {
"children": {
"_parent": {
"type": "person"
}
},
"pets": {
"_parent": {
"type": "person"
}
}
}
}'
Next, index all the documents - parents, children and pets.
# Index documents
curl -XPOST "$ELASTICSEARCH_ENDPOINT/_bulk?refresh=true" -d '
{"index":{"_index":"es-joins","_type":"person","_id":1}}
{"name":"Bill","gender":"male"}
{"index":{"_index":"es-joins","_type":"person","_id":2}}
{"name":"Bob","gender":"male"}
{"index":{"_index":"es-joins","_type":"person","_id":3}}
{"name":"Mary","gender":"female"}
{"index":{"_index":"es-joins","_type":"person","_id":4}}
{"name":"Jane","gender":"female"}
{"index":{"_index":"es-joins","_type":"children","_parent":1,"_id":1}}
{"name":"Adam","gender":"male"}
{"index":{"_index":"es-joins","_type":"children","_parent":1,"_id":2}}
{"name":"Eve","gender":"female"}
{"index":{"_index":"es-joins","_type":"children","_parent":3,"_id":3}}
{"name":"Lamb","gender":"male"}
{"index":{"_index":"es-joins","_type":"children","_parent":4,"_id":4}}
{"name":"Xander","gender":"male"}
{"index":{"_index":"es-joins","_type":"pets","_parent":1,"_id":1}}
{"name":"Apple","type":"dog"}
{"index":{"_index":"es-joins","_type":"pets","_parent":4,"_id":2}}
{"name":"Buffy","type":"cat"}
{"index":{"_index":"es-joins","_type":"pets","_parent":4,"_id":3}}
{"name":"Willow","type":"dog"}
'
Now we can do some searches on it.
The usual example will be searching a parent by its children. Lets find
all the parents that has a girl. We expect to get back only Bill.
curl -XPOST "$ELASTICSEARCH_ENDPOINT/es-joins/person/_search?pretty" -d '
{
"query": {
"filtered": {
"filter": {
"and": [
{
"has_child": {
"type": "children",
"query": {
"term": {
"gender": "female"
}
}
}
}
]
}
}
}
}
'
We can also combine conditions on multiple child types.
Lets find parents that have a boy and a dog. This time we expect to get back both Bill and Jane.
curl -XPOST "$ELASTICSEARCH_ENDPOINT/es-joins/person/_search?pretty" -d '
{
"query": {
"filtered": {
"filter": {
"and": [
{
"has_child": {
"type": "children",
"query": {
"term": {
"gender": "male"
}
}
}
},
{
"has_child": {
"type": "pets",
"query": {
"term": {
"type": "dog"
}
}
}
}
]
}
}
}
}
'
Another commonly used option is finding children by their parents.
But a more interesting possibility is finding children by their siblings.
Lets lookup all boys that have a dog. To do that we’re searching on the
“children” type, and doing a has_parent filter that contains a has_child
filter on the “pets” type.
This time we expect to get back the children - Adam and Xander.
curl -XPOST "$ELASTICSEARCH_ENDPOINT/es-joins/children/_search?pretty" -d '
{
"query": {
"filtered": {
"filter": {
"and": [
{
"has_parent": {
"parent_type": "person",
"filter": {
"has_child": {
"type": "pets",
"query": {
"term": {
"type": "dog"
}
}
}
}
}
},
{
"term": {
"gender": "male"
}
}
]
}
}
}
}
'
Of course, our data model here is a bit simplified as it allows only a single parent. If we were to extend it, we would create a “family” parent type, with child types - “parents”, “children” and “pets”.
Currently, in order to get the details of the “joined” entity, another query is needed. For example, when searching “all boys that have a dog”, if we want the details of the dogs we need a second search for “all dogs with parents that have children with _id=…” (and the _ids of the children from the first search).
This will change with the new upcoming inner hits feature that will allow getting the data of the inner entities in a single query.
One should note that this method is not exactly recommended by
Elasticsearch. Because of the memory requirements and performance hit,
the official recommendation is: “Avoid using multiple parent-child joins in a single query”. So as always, test, measure and choose your modeling wisely.
[转]Cross-type joins in Elasticsearch的更多相关文章
- 自己写的数据交换工具——从Oracle到Elasticsearch
先说说需求的背景,由于业务数据都在Oracle数据库中,想要对它进行数据的分析会非常非常慢,用传统的数据仓库-->数据集市这种方式,集市层表会非常大,查询的时候如果再做一些group的操作,一个 ...
- ElasticSearch+NLog+Elmah实现Asp.Net分布式日志管理
本文将介绍使用NLOG.Elmah结合ElasticSearch实现分布式日志管理. 一.ElasticSearch简介 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布 ...
- Elasticsearch: Indexing SQL databases. The easy way
Elasticsearchis a great search engine, flexible, fast and fun. So how can I get started with it? Thi ...
- elasticsearch插件大全
Elasticsearch扩展性非常好,有很多官方和第三方开发的插件,下面以分词.同步.数据传输.脚本支持.站点.其它这几个类别进行划分. 分词插件 Combo Analysis Plugin (作者 ...
- 安装elasticsearch
安装elasticsearch 来自:http://www.cnblogs.com/huangfox/p/3541300.html 一)安装elasticsearch 1)下载elasticsea ...
- ElasticSearch中文分词(IK)
ElasticSearch常用的很受欢迎的是IK,这里稍微介绍下安装过程及测试过程. 1.ElasticSearch官方分词 自带的中文分词器很弱,可以体检下: [zsz@VS-zsz ~]$ c ...
- Elasticsearch和mysql数据同步(elasticsearch-jdbc)
1.介绍 对mysql.oracle等数据库数据进行同步到ES有三种做法:一个是通过elasticsearch提供的API进行增删改查,一个就是通过中间件进行数据全量.增量的数据同步,另一个是通过收集 ...
- Logstash同步Oracle数据到ElasticSearch
最近在项目上应用到了ElasticSearch和Logstash,在此主要记录了Logstash-input-jdbc同步Oracle数据库到ElasticSearch的主要步骤,本文是对环境进行简单 ...
- ELK( ElasticSearch+ Logstash+ Kibana)分布式日志系统部署文档
开始在公司实施的小应用,慢慢完善之~~~~~~~~文档制作 了好作运维同事之间的前期普及.. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 软件下载地址: https://www.e ...
随机推荐
- 【LeetCode】Permutation全排列
1. Next Permutation 实现C++的std::next_permutation函数,重新排列范围内的元素,返回按照 字典序 排列的下一个值较大的组合.若其已经是最大排列,则返回最小排列 ...
- [洛谷 P2709] 小B的询问
P2709 小B的询问 题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数 ...
- QWebView崩溃的问题
http://www.cnblogs.com/kobe-echo/p/5720765.html#undefined
- python+ajaxFileUpload 无刷新上传文件
需要准备文件 http://pan.baidu.com/s/1bp4N3nL qqi0 html <script src="{% static 'js/jquery.js' %}& ...
- Win10系列:JavaScript页面导航
页面导航是在开发应用的过程中使用频率较高的技术,其中比较常用的导航方式有多页导航和页内导航,采用多页导航方式的应用程序包含一系列的页面,在一个页面中加入另一个页面的链接地址后,单击链接将跳转到指定页面 ...
- Win10系列:JavaScript 项目模板中的文件和项模板文件
通过上面内容的学习,相信读者已经对各种项目模板和项模板有了大致的了解,本节将进一步介绍项目模板中默认包含的项目文件以及项模板文件,首先讲解这些文件中的初始内容以及作用,然后介绍在一个页面中如何添加控件 ...
- Win10系列:JavaScript 项目模板和项模板
使用Visual Studio 开发Windows应用商店应用时,通过其提供的模板可以帮助我们快速地创建一个应用.其中,在新建一个Windows应用商店应用程序项目时可以在项目模板中选择所需要的模板类 ...
- 面向对象之 组合 封装 多态 property 装饰器
1.组合 什么是组合? 一个对象的属性是来自另一个类的对象,称之为组合 为什么要用组合 组合也是用来解决类与类代码冗余的问题 3.如何用组合 # obj1.xxx=obj2''''''# class ...
- Yii2.0 数据库查询 [ 2.0 版本 ]
下面介绍一下 Yii2.0 对数据库 查询的一些简单的操作 User::find()->all(); 此方法返回所有数据: User::findOne($id); 此方法返回 主键 id=1 的 ...
- HTML(二)选择器
1.id选择器 一对一关系 <div id="only">123</div> #only{ background-color:black; } 2.clas ...