前言
公司最近的需求有用到索引的关联关系查询,经过查询资料得知 Elasticsearch6.0 之后只支持使用 join datatype 方式构建父子关系文档,下面来介绍一下具体怎么使用。
创建索引
es中指定关联关系和数据库不同,es中有个join数据类型,是创建相同的索引文件中的父/子关系的特殊领域,建立父子关系最重要的一步是在创建索引的时候在mapping中声明某个字段是join类型字段,并且指定字段的值哪个是父文档哪个是子文档:
$host = ['192.168.1.10:9200'];
$client = ClientBuilder::create()->setHosts($host)->build();
$params = [
'index' => 'my_index', // 索引名称
'body' => [
'mappings' => [
'properties' => [ // 设置字段类型
'my_join_field' => [ // 字段名称
'type' => 'join', // 字段类型,join类型表示是联接数据类型
'relations' => [ // 指定连接关系 '父' => '子'
'parent' => 'child', // 一父一子
'parent_2' => ['child_1','child_2'] // 一父多子
]
]
]
]
]
];
$response = $client->indices()->create($params);
以上代码指定了my_index 索引文档中my_join_field字段的值为 parent 是 child 的的父文档,parent_2是child_1和child_2的父文档。
新增父文档数据
新增父文档的时候只需要设置my_join_field字段的值为parent就可以了
$host = ['192.168.1.10:9200'];
$client = ClientBuilder::create()->setHosts($host)->build();
$params = [
'index' => 'my_index',
'type' => '_doc',
'id' => 1,
'body' => [
'parent_name' => '测试父文档',
'parent_one' => 'test_test',
'parent_two' => 12312421,
'my_join_field' => [
'name' => 'parent' // 指定文档为父文档,只需要把值设置成上面定义好的parent
]
]
];
$response = $client->index($params);
上面代码已经添加了一个id为1的文档并且把该文档的联接类型设置成了parent
新增子文档
$host = ['192.168.1.10:9200'];
$client = ClientBuilder::create()->setHosts($host)->build();
$params = [
'index' => 'my_index',
'type' => '_doc',
'id' => 2,
'routing' => 1, // 指定该文档存储的分片,设置子文档的必须项,必须和父文档存储在同一个分片中
'body' => [
'child_name' => '第一个子文档',
'child_one' => 'test_test',
'child_two' => 12312421,
'my_join_field' => [
'name' => 'child', // 指定文档为子文档类型,把值设置成上面定义好的child
'parent' => 1 // 指定关联父文档的文档id
]
]
];
$response = $client->index($params);
上面代码指定了一个id为2的文档是子文档,并且父文档的id是1
注意:设置子文档的时候routing是必填项,不传会抛出异常。
通过父文档查询子文档
$host = ['192.168.1.10:9200'];
$client = ClientBuilder::create()->setHosts($host)->build();
$params = [
'index' =>'my_index', // 索引名
'type' => '_doc',
'body' => [
'from' => 0, // 偏移量
'size' => 10, // 查询多少条
'query' => [
'has_parent' => [ // 连接父文档查询
'parent_type' => 'parent', // 指定查询的父文档
'query' => [ // 查询条件
'match' => [
'parent_name' => '父'
]
]
]
]
]
];
$response = $client->search($params);
以上代码表示查询父文档为parent并且父文档中parent_name字段值中有 “父” 这个词的子文档。
注意:通过父文档查询子文档的时候不会返回父文档的数据
通过子文档查询父文档
$host = ['192.168.1.10:9200'];
$client = ClientBuilder::create()->setHosts($host)->build();
$params = [
'index' =>'my_index', // 索引名
'type' => '_doc',
'body' => [
'from' => 0, // 偏移量
'size' => 10, // 查询多少条
'query' => [
'has_child' => [ // 连接父文档查询
'type' => 'child', // 指定查询的父文档
'query' => [ // 查询条件
'match' => [
'child_name' => '子'
]
]
]
]
]
];
$response = $client->search($params);
以上代码表示查询子文档为child并且子文档中child_name字段值中有 “子” 这个词的父文档。
注意:通过子文档查询父文档的时候不会返回子文档的数据