安装
环境要求
- 大于等于php7.1
- 需要安装composer
- 需要CURL扩展
- 原生JSON扩展(ext-json) 1.3.7或更高
通过composer安装
composer require elasticsearch/elasticsearch
连接
通过Http认证方式初始化
$hosts = [
'http://user:pass@localhost:9200', // 一定要加端口号,不然有可能会连接失败,即便是80端口也要添加
];
$client = ClientBuilder::create()
->setHosts($hosts)
->setRetries(2) # 重试连接次数
->setElasticMetaHeader(false) # 禁止在header头中发送es服务信息
->build();
新建一个文档
指定文档id创建
我们需要指定三段信息:索引(索引不存在时会自动创建)、id和文档主体。这是通过构造键:值对的关联数组来实现的。请求体本身就是一个关联数组,键:值对对应于文档中的数据:
$params = [
'index' => 'my_index',
'id' => 'my_id',
'body' => ['testField' => 'abc']
];
$response = $client->index($params);
print_r($response);
# 返回值
Array
(
[_index] => my_index # 索引
[_type] => _doc # 文档类型
[_id] => my_id # 文档id
[_version] => 1 # 文档版本号
[created] => 1
)
自动生成id方式创建
$params = [
'index' => 'my_index',
'body' => ['testField' => 'abc']
];
$response = $client->index($params);
print_r($response);
创建文档其他的参数
$params = [
'index' => 'my_index',
'id' => 'my_id',
'routing' => 'company_xyz',
'timestamp' => strtotime("-1d"),
'body' => [ 'testField' => 'abc']
];
$response = $client->index($params);
批量创建索引
for($i = 0; $i < 100; $i++) {
$params['body'][] = [
'index' => [
'_index' => 'my_index',
]
];
$params['body'][] = [
'my_field' => 'my_value',
'second_field' => 'some more values'
];
}
$responses = $client->bulk($params);
上边组成的数组格式就类似于这样:
array:1 [▼
"body" => array:2 [▼
0 => array:1 [▼
"index" => array:1 [▼
"_index" => "wiki"
]
]
1 => array:3 [▼
"id" => "2"
"title" => "这是批量插入的"
"description" => "测试一下批量插入的"
]
2 => array:1 [▼
"index" => array:1 [▼
"_index" => "wiki"
]
]
3 => array:3 [▼
"id" => "2"
"title" => "这是批量插入的"
"description" => "测试一下批量插入的"
]
]
]
获取一个文档
通过id获取一个文档
$params = [
'index' => 'my_index',
'id' => 'my_id'
];
$response = $client->get($params);
print_r($response);
# 返回结果
Array
(
[_index] => my_index # 索引
[_type] => _doc # 文档类型
[_id] => my_id # 文档id
[_version] => 1 # 文档版本号
[found] => 1
[_source] => Array # 文档内容
(
[testField] => abc
)
)
更新文档
更新文档允许您完全替换现有文档的内容,或者只对一些字段执行部分更新(更改现有字段或添加新字段)。
部分更新
$params = [
'index' => 'my_index',
'id' => 'my_id',
'body' => [
'doc' => [
'new_field' => 'abc' # 需要更新的字段
]
]
];
$response = $client->update($params);
脚本化更新
有时您需要执行脚本化的更新,例如递增计数器或向数组添加新值。要执行脚本更新,您需要提供一个脚本
$params = [
'index' => 'my_index',
'id' => 'my_id',
'body' => [
'script' => 'ctx._source.counter += count', # 需要执行的脚本
'params' => [
'count' => 4
]
]
];
$response = $client->update($params);
upserts参数
Upserts是“更新或插入”操作。这意味着upsert会尝试运行您的更新脚本,但是如果文档不存在(或者您试图更新的字段不存在),则会插入默认值。
$params = [
'index' => 'my_index',
'id' => 'my_id',
'body' => [
'script' => [
'source' => 'ctx._source.counter += params.count',
'params' => [
'count' => 4
],
],
'upsert' => [
'counter' => 1
],
]
];
$response = $client->update($params);
删除文档
删除指定id的文档
$params = [
'index' => 'my_index',
'id' => 'my_id'
];
$response = $client->delete($params);
搜索
简单的列子
$params = [
'index' => 'my_index',
'body' => [
'query' => [
'match' => [
'testField' => 'abc'
]
],
'highlight' => array[
'fields' => array[
'content' => new \stdClass() # 如果参数中想传入个空的话,必须这样写
]
]
]
];
$response = $client->search($params);
print_r($response);
# 返回结果
Array
(
[took] => 1
[timed_out] =>
[_shards] => Array
(
[total] => 5
[successful] => 5
[failed] => 0
)
[hits] => Array
(
[total] => 1 # 有几条数据
[max_score] => 0.30685282
[hits] => Array #返回的搜索文档的结果
(
[0] => Array
(
[_index] => my_index
[_type] => _doc
[_id] => my_id
[_score] => 0.30685282 # 匹配分数,分数越高越靠前
[_source] => Array
(
[testField] => abc
)
)
)
)
)
match匹配搜索
$params = [
'index' => 'my_index', # 指定索引
'body' => [
'query' => [
'match' => [
'testField' => 'abc' # 字段匹配条件
]
]
]
];
$results = $client->search($params);
使用原始json方式请求
有时,为了测试目的或者从不同的系统迁移时,使用原始JSON很方便。你可以在body中使用raw JSON作为字符串,客户端会自动检测到这一点
$json = '{
"query" : {
"match" : {
"testField" : "abc"
}
}
}';
$params = [
'index' => 'my_index',
'body' => $json
];
$results = $client->search($params);
bool查询
$params = [
'index' => 'my_index',
'body' => [
'query' => [
'bool' => [
'must' => [
[ 'match' => [ 'testField' => 'abc' ] ],
[ 'match' => [ 'testField2' => 'xyz' ] ],
]
]
]
]
];
$results = $client->search($params);
复杂案例
$params = [
'index' => 'my_index',
'body' => [
'query' => [
'bool' => [
'filter' => [ # 过滤查询
'term' => [ 'my_field' => 'abc' ]
],
'should' => [
'match' => [ 'my_other_field' => 'xyz' ]
]
]
]
]
];
$results = $client->search($params);
删除一个文档
$params = [
'index' => 'my_index',
'id' => 'my_id'
];
$response = $client->delete($params);
print_r($response);
# 返回结果
Array
(
[found] => 1
[_index] => my_index
[_type] => _doc
[_id] => my_id
[_version] => 2
)
删除文档
$deleteParams = [
'index' => 'my_index'
];
$response = $client->indices()->delete($deleteParams);
print_r($response);
# 返回结果
Array
(
[acknowledged] => 1
)
新建索引
简单列子
$params = [
'index' => 'my_index',
'body' => [
'settings' => [
'number_of_shards' => 2,
'number_of_replicas' => 0
],
'mappings' => [
'_source' => [
'enabled' => true
],
'properties' => [
'first_name' => [
'type' => 'keyword'
],
'age' => [
'type' => 'integer'
]
]
]
]
];
$response = $client->indices()->create($params);
print_r($response);
# 返回结果
Array
(
[acknowledged] => 1
)
复杂案例
$params = [
'index' => 'reuters',
'body' => [
'settings' => [ # 设置包含关于索引(分片的编号等)和分析器的配置。
'number_of_shards' => 1,
'number_of_replicas' => 0,
'analysis' => [ # 分析嵌套在设置中,并包含标记器、过滤器、字符过滤器和分析器。
'filter' => [
'shingle' => [
'type' => 'shingle'
]
],
'char_filter' => [
'pre_negs' => [
'type' => 'pattern_replace',
'pattern' => '(\\w+)\\s+((?i:never|no|nothing|nowhere|noone|none|not|havent|hasnt|hadnt|cant|couldnt|shouldnt|wont|wouldnt|dont|doesnt|didnt|isnt|arent|aint))\\b',
'replacement' => '~$1 $2'
],
'post_negs' => [
'type' => 'pattern_replace',
'pattern' => '\\b((?i:never|no|nothing|nowhere|noone|none|not|havent|hasnt|hadnt|cant|couldnt|shouldnt|wont|wouldnt|dont|doesnt|didnt|isnt|arent|aint))\\s+(\\w+)',
'replacement' => '$1 ~$2'
]
],
'analyzer' => [
'reuters' => [
'type' => 'custom',
'tokenizer' => 'standard',
'filter' => ['lowercase', 'stop', 'kstem']
]
]
]
],
'mappings' => [ # Mappings是嵌套在设置中的另一个元素,它包含各种类型的映射。
'properties' => [
'title' => [
'type' => 'text',
'analyzer' => 'reuters',
'copy_to' => 'combined'
],
'body' => [
'type' => 'text',
'analyzer' => 'reuters',
'copy_to' => 'combined'
],
'combined' => [
'type' => 'text',
'analyzer' => 'reuters'
],
'topics' => [
'type' => 'keyword'
],
'places' => [
'type' => 'keyword'
]
]
]
]
];
$client->indices()->create($params);
删除索引
$params = ['index' => 'my_index'];
$response = $client->indices()->delete($params);
修改索引
$params = [
'index' => 'my_index',
'body' => [
'settings' => [
'number_of_replicas' => 0,
'refresh_interval' => -1
]
]
];
$response = $client->indices()->putSettings($params);
查询一个或多个索引
查询一个索引
$params = ['index' => 'my_index'];
$response = $client->indices()->getSettings($params);
查询多个索引
$params = [
'index' => [ 'my_index', 'my_index2' ]
];
$response = $client->indices()->getSettings($params);
给已存在的索引添加mappings
$params = [
'index' => 'my_index',
'body' => [
'_source' => [
'enabled' => true
],
'properties' => [
'first_name' => [
'type' => 'text',
'analyzer' => 'standard'
],
'age' => [
'type' => 'integer'
]
]
]
];
$client->indices()->putMapping($params);
获取索引的mappings
// 获取所有的
$response = $client->indices()->getMapping();
// 获取指定一个的
$params = ['index' => 'my_index'];
$response = $client->indices()->getMapping($params);
// 获取指定多个的
$params = [
'index' => [ 'my_index', 'my_index2' ]
];
$response = $client->indices()->getMapping($params);