一、前言
最近在把ELK
升级到7.0
之后,发现使用的ES-PHP
并不兼容7.0
的版本,可能作者正在努力开发新版本中吧。不过身为使用者,目前还是尽量少用7.0
的一些新特性吧,兼容旧版本的ES还是可以的。
二、问题
1、使用match_all报错
(1)报错信息:
{"error":{"root_cause":[{"type":"parsing_exception","reason":"[match_all] query malformed, no start_object after query name","line":1,"col":45}],"type":"parsing_exception","reason":"[match_all] query malformed, no start_object after query name","line":1,"col":45},"status":400}
错误原因是: 查询格式错误,查询名称后没有start_object(没错,是有道翻译的),很奇怪,在网络上看到很多直接使用这种方式进行全文搜索的,但是用ES-PHP就不行。
GET /_search
{
"query": {
"match_all": {}
}
}
2、问题改进
突然想起来刚开始看ES-PHP
文档的时候就说过,PHP是采用数组的方式拼接DSL,不能有空数组,因为问题就在于 PHP 会自动把 "content" : {} 转换成 "content" : []
,在 Elasticsearch DSL
中这样的数据格式是非法的。我们需要告诉 PHP 那个空对象就是一个空对象而非空数组。
那么改进为:
"match_all"=> new \stdClass()
官方手册:https://www.elastic.co/guide/cn/elasticsearch/php/current/php_json_objects.html
3、google一下
在网上也发现有人提过这个issues,开发团队给出的建议是:
"match_all"=> (object)[] //也是给出空数组的方式
github讨论:https://github.com/elastic/elasticsearch-php/issues/495
三、更新mapping的时候报错
就像标题一样,当我尝试更新mapping的时候,报错了,错误如下:
Types cannot be provided in put mapping requests, unless the include_type_name parameter is set to true
1、原因
随着 7.0
版本的即将发布,type
的移除也是越来越近了,在 6.0
的时候,已经默认只能支持一个索引一个 type
了,7.0
版本新增了一个参数 include_type_name
,即让所有的 API 是 type
相关的,这个参数在 7.0
默认是 true
,不过在 8.0
的时候,会默认改成 false
,也就是不包含 type
信息了,这个是 type
用于移除的一个开关。
参考:https://elasticsearch.cn/article/601
大概意思就是ES版本更新的问题,现在的type
已经不用那么明显的指定出来了。查看官方的更新mapping
操作,在DSL
里面也没有明确的指出type
。但是对于ES-PHP
,因为不兼容最新的es7.0
,所以更改mapping
要求必须带有type
,源码如下:
//源码在 vendor\elasticsearch\elasticsearch\src\Elasticsearch\Namespaces\IndicesNamespace.php 的第600行
public function putMapping($params)
{
$index = $this->extractArgument($params, 'index');
$type = $this->extractArgument($params, 'type');
$body = $this->extractArgument($params, 'body');
/** @var callback $endpointBuilder */
$endpointBuilder = $this->endpoints;
/** @var \Elasticsearch\Endpoints\Indices\Mapping\Put $endpoint */
$endpoint = $endpointBuilder('Indices\Mapping\Put');
$endpoint->setIndex($index)
->setType($type)
->setBody($body);
$endpoint->setParams($params);
return $this->performRequest($endpoint);
}
源码要求必须带有type
,所以就报错了。行叭,按照错误提示,需要加的这个参数,ES-PHP
貌似也识别不了,所以有关mapping
的一些操作就只能等待版本的更新了。
2、解决方案
博主在github上面提交了一条issues
,有大佬指点了一条道路:
$params = [
'index' => 'user',
'custom' => [
'include_type_name' => true
],
'type'=>'_doc',
'body' => [
'properties' => [
]
]
$response = $client->indices()->putMapping();
print_r($response);
通过传参解决的,这边的传参要遵循固定的格式,下面为参考链接:
官方文档: https://github.com/elastic/elasticsearch-php/blob/master/docs/per-request-configuration.asciidoc#providing-custom-query-parameters
issues: https://github.com/elastic/elasticsearch-php/issues/883
end