Press "Enter" to skip to content

PHP 操作 Elasticsearch 父子关系索引创建、搜索

前言

公司最近的需求有用到索引的关联关系查询,经过查询资料得知 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字段值中有 “子” 这个词的父文档。
==注意:通过子文档查询父文档的时候不会返回子文档的数据==

注意事项

1.关联关系建立了后,只运行新增关系,不支持删除或修改

发表评论

邮箱地址不会被公开。 必填项已用*标注