使用elasticsearch-php需要注意的match_all和mapping問題

一、前言
      最近在把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
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章