[转]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 ...
随机推荐
- docker实战系列之搭建rabbitmq
1.搜索镜像[注:因为我这里采用的是阿里云镜像加速器,所以我直接在阿里云中搜索相关镜像路径],点击"详情"查看公网拉取路径 2.拉取镜像 docker pull registry. ...
- ORM框架之SQLALchemy
一.面向对象应用场景: 1.函数有共同参数,解决参数不断重用: 2.模板(约束同一类事物的,属性和行为) 3.函数编程和面向对象区别: 面向对象:数据和逻辑组合在一起:函数编程:数据和逻辑不能组合在一 ...
- 反向代理/负载均衡/session/cookie
正向代理:客户端将流量重定向到burpsuite等软件或连接到VPN再访问服务器而不是直接访问服务器的场景.流量流动方向是真正机器--代理服务器.正向代理又称代理.普通代理. 反向代理:服务器端使用反 ...
- axure rp安装
axure rp安装 1◆ axure rp 文件下载 2◆创建安装目录 3◆ 安装图解 4◆汉化 替换 5◆ 使用 success 1★AxureRP 8.0安装包 2★ ...
- MySql多个count查询
现有一个student表结构数据如下: id hight sex age 1 160 0 16 2 170 1 16 3 180 1 17 4 160 1 16 5 170 ...
- react中用pace.js
pace.js不支持npm, 所以只能直接下载下来,当作普通js引入 我在用的时候怎么都引不到组件里去用 后来终于找到方法了,直接上图了 1.先将pace文件下载来放在公共js目录下,pace.les ...
- eclipse.ini参数配置
-vmD:/jdk1.6/Java/jdk1.6.0_45/bin/javaw.exe-vmargs-Xms1024m-Xmx1024m-XX:MaxPermSize=1024m-XX:Reserve ...
- python全栈开发笔记-----------概要
Python开发 开发: 开发语言: 高级语言:python.Java.php .C# .Go .ruby . C++ .... ===>字节码 低级语言:C.汇编 ...
- TNetHTTPClient 使用
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System ...
- asp.net webapi 返回json结果的方法
第一种: public static void Register(HttpConfiguration config) { //1.将默认的xml格式化程序清除 GlobalConfiguration. ...