<?php
namespace app\elasticsearch;
use Elasticsearch\Client;
use Elasticsearch\ClientBuilder;
use Elasticsearch\ConnectionPool\StaticNoPingConnectionPool;
use Elasticsearch\ConnectionPool\Selectors\RoundRobinSelector;
// https://www.blsa.cn/articles/201
class ParentChildEs
{
/** @var Client es连接 */
private $client;
private $indexName = 'parent_child';
private $type = '_doc';
public function __construct()
{
$hosts = [
'host' => '192.168.213.128'
];
$this->client = ClientBuilder::create()
// 连接池:维持一份连接清单,它决定节点在什么时候从活节点转变为死节点(或死节点转变为活节点)
->setConnectionPool(StaticNoPingConnectionPool::class, [])
// 选择器:连接池选择连接对象时是没有逻辑的
->setSelector(RoundRobinSelector::class)
->setHosts($hosts)
->build();
}
// -------------------------索引mapping
// 创建索引
public function create()
{
$params = [
'index' => $this->indexName,
'body' => [
'settings' => [
'number_of_shards' => 1, // 分片数
'number_of_replicas' => 0, // 副本数
'index' => [ // 设置默认分词器
"analysis.analyzer.default.type" => "ik_max_word"
]
],
]
];
$res = $this->client->indices()->create($params);
}
// 1. 设置索引的mapping
public function setMapping(): void
{
$this->create();
$params = [
'index' => $this->indexName,
'type' => $this->type,
'include_type_name' => true,
'body' => [
$this->type => [
'properties' => [
'company_id' => ['type' => 'keyword'],
'name' => ['type' => 'text'],
'parent_join' => [
'type' => 'join',
'relations' => ['parent_company' => 'sub_company']
]
]
]
]
];
$res = $this->client->indices()->putMapping($params);
var_dump($res);
}
// 2. 插入父文档数据
public function bulkParent(): void
{
$data = [
[
'company_id' => '1',
'name' => '阿里巴巴',
'parent_join' => ['name' => 'parent_company'],
],
[
'company_id' => '2',
'name' => '杭州阿里巴巴',
'parent_join' => ['name' => 'parent_company'],
],
[
'company_id' => '3',
'name' => '小米',
'parent_join' => ['name' => 'parent_company'],
],
[
'company_id' => '4',
'name' => '北京小米',
'parent_join' => ['name' => 'parent_company'],
],
];
$bulk = [];
foreach ($data as $item) {
$bulk['body'][] = [
'index' => [
'_index' => $this->indexName,
'_type' => '_doc',
'_id' => $item['company_id'],
]
];
$bulk['body'][] = $item;
}
$response = $this->client->bulk($bulk);
var_dump($response);
exit;
}
// 3. 插入子文档数据
public function bulkChild(): void
{
$data = [
[
'patent_name' => '阿里巴巴专利1',
'time' => 123,
'parent_join' => ['name' => 'sub_company', 'parent' => 1],
],
[
'patent_name' => '阿里巴巴专利2',
'time' => 888,
'parent_join' => ['name' => 'sub_company', 'parent' => 2],
],
[
'patent_name' => '小米专利1',
'time' => 123,
'parent_join' => ['name' => 'sub_company', 'parent' => 3],
],
[
'patent_name' => '小米专利1',
'time' => 888,
'parent_join' => ['name' => 'sub_company', 'parent' => 4],
],
];
$bulk = [];
foreach ($data as $item) {
$bulk['body'][] = [
'index' => [
'_index' => $this->indexName,
'_type' => '_doc',
'_id' => $item['parent_join']['parent'] . '-1',
'routing' => $item['parent_join']['parent'],
]
];
$bulk['body'][] = $item;
}
$response = $this->client->bulk($bulk);
var_dump($response);
exit;
}
// 父子文档 https://www.elastic.co/guide/en/elasticsearch/guide/master/parent-child.html
// has_child 查询,返回父文档
public function hasChild(): void
{
$params = [
'index' => $this->indexName,
'type' => $this->type,
'body' => [
// 查询父文档
'query' => [
'has_child' => [
'type' => 'sub_company',
'query' => [
'match' => ['patent_name' => '小米'],
],
],
],
],
];
$response = $this->client->search($params);
var_dump($response);
}
// has_parent 查询,返回子文档
public function hasParent(): void
{
$params = [
'index' => $this->indexName,
'type' => $this->type,
'body' => [
// 查询子文档
'query' => [
'has_parent' => [
'parent_type' => 'parent_company',
'query' => [
'match' => ['name' => '小米'],
],
],
],
],
];
$response = $this->client->search($params);
var_dump($response);
}
// 查询所有
public function search()
{
$params = [
'index' => $this->indexName,
'type' => $this->type,
];
$res = $this->client->search($params);
var_dump($res);
}
// 根据父id查询,不含子文档
public function byParentId(): void
{
$params = [
'index' => $this->indexName,
'type' => $this->type,
'id' => 1,
];
var_dump($this->client->get($params));
}
// 复杂bool查询
public function complexBool(): void
{
$params = [
'index' => $this->indexName,
'type' => $this->type,
'body' => [
'query' => [
'bool' => [
'must' => [
[
'has_child' => [
'type' => 'sub_company',
'query' => [
'bool' => [
'must' => [
[
'range' => [
'time' => ['gte' => 300, 'lte' => 900]
]
]
]
]
]
]
],
[
'match' => [
'name' => '阿里巴巴'
]
]
]
]
]
],
];
var_dump($this->client->search($params));
}
}