Elasticsearch index_options = docs для текстового типа данных не возвращает никаких результатов поиска

Я использую Elasticsearch 7.6 и клиентский API PHP для всех операций. Я создал настройки и сопоставления индекса elasticsearch следующим образом

$params = [
    'index' => 'elasticindex',
    'body' => [
        'settings' => [
            "number_of_shards" => 1,
            "number_of_replicas" => 0,
            "index.queries.cache.enabled" => false,
            "index.soft_deletes.enabled" => false,
            "index.requests.cache.enable" => false,
            "index.refresh_interval" => -1
        ],
        'mappings' => [
            '_source' => [
                "enabled" => false
             ],
            'properties' => [
                "text" => [
                        "type" => "text",
                        "index_options" => "docs"
                ]
            ]
     ]
    ]
];

Мне удалось проиндексировать документ, используя следующий код

$params = array();
$params['index'] = 'elasticindex';
for($i = 1; $i <=2; $i++) {
        $params['id'] = $i;
        $params['body']['text'] = 'apple';
        $responses = $client->index($params);
}

Но когда я использую следующий поисковый запрос

  $params = [
        'index' => 'elasticindex',
        'body'  => [
            'query' => [
                'match' => [
                    "text" => "apple"
                ]
            ]
        ]
    ];

$results = $client->search($params);

Я получаю пустые результаты следующим образом

Array                                                                                                                                                   
   (                                                                                                                                                       
    [took] => 3                                                                                                                                         
    [timed_out] =>                                                                                                                                      
    [_shards] => Array                                                                                                                                  
        (                                                                                                                                               
            [total] => 1                                                                                                                                
            [successful] => 1                                                                                                                           
            [skipped] => 0                                                                                                                              
            [failed] => 0                                                                                                                               
        )                                                                                                                                               

    [hits] => Array         
        (          
            [total] => Array                                       
                (                                                    
                    [value] => 0
                    [relation] => eq
                )           

            [max_score] =>   
            [hits] => Array
                (          
                )     

        )               

) 

Без создания шаблона статического индекса, если я попытаюсь выполнить индексацию, динамическое сопоставление elasticsearch будет работать хорошо, и я получаю результаты.

Цель состоит в том, чтобы эластичный поиск индексировал только идентификатор документа в своем инвертированном индексе, а не позицию или смещение, и я хочу получать только совпадающие идентификаторы документов в качестве результатов. Помощь очень ценится. Заранее спасибо!


person Mohamed Abdullah    schedule 10.05.2020    source источник
comment
Вероятно, вы захотите включить поле id в свое статическое сопоставление: "id": { "type": "keyword"}, Используйте <host>:9200/elasticsearch/_search?q=*:*, чтобы увидеть, был ли ваш документ вообще проиндексирован (я бы выбрал имя индекса лучше, чем elasticsearch, кстати. :-)   -  person MatsLindh    schedule 10.05.2020
comment
Можете ли вы показать мне один документ из elastic, не применяйте никаких фильтров запросов, просто установите размер как 1, получите один документ и разместите здесь.   -  person jithu thomas    schedule 10.05.2020
comment
@MatsLindh Я получил следующий ответ на ваш запрос URL {take: 2, timed_out: false, _shards: {total: 1, success: 1, skipped: 0, failed: 0}, hits: {total: {value : 0, отношение: eq}, max_score: null, hits: []}}. Означает ли это, что мой документ не индексируется?   -  person Mohamed Abdullah    schedule 10.05.2020
comment
@jithuthomas Я попытался получить документ с идентификатором 1 и получил этот массив ответов ([_index] = ›elasticindex [_type] =› _doc [_id] = ›1 [_version] =› 1 [_seq_no] = ›0 [ _primary_term] = ›1 [найдено] =› 1)   -  person Mohamed Abdullah    schedule 10.05.2020
comment
@MatsLindh Кроме того, я попытался создать статическое сопоставление для поля id, но все тот же пустой ответ   -  person Mohamed Abdullah    schedule 10.05.2020
comment
Вы неправильно проиндексировали документ. Неэластичный документ Ни один из документов не имеет значения яблоко. Я добавлю ответ, как индексировать образец документа и как его можно запросить.   -  person jithu thomas    schedule 10.05.2020
comment
@MohamedAbdullah Верно. Поскольку вы не получаете обратно никаких документов, возникла проблема при их индексировании. Журнал Elasticsearch должен отображать ошибку о том, что документ не индексируется должным образом.   -  person MatsLindh    schedule 10.05.2020
comment
@MatsLindh лог чист. я не получаю сообщений об ошибках, более того, если я использую API get, он говорит found = 1.   -  person Mohamed Abdullah    schedule 11.05.2020
comment
Вы запрашиваете документ сразу после его отправки в индекс? Или это две отдельные операции? Документ станет доступен в GET интерфейсе до, когда он станет доступным для общего поиска - последний требует, чтобы сначала произошло обновление индекса. Возможно, вам потребуется добавить refresh=wait_for в URL-адрес запроса индексации.   -  person MatsLindh    schedule 11.05.2020
comment
@MatsLindh, да, это две отдельные операции. Я сначала индексирую, а потом ищу   -  person Mohamed Abdullah    schedule 11.05.2020
comment
@MatsLindh, ты прав. Поскольку я использую этот index.refresh_interval = ›-1, индекс не готов для поиска. как только я обновил индекс, я получил результаты. Спасибо большое за вашу помощь!   -  person Mohamed Abdullah    schedule 11.05.2020
comment
Хороший улов! Я этого не видел, но это объясняет :-)   -  person MatsLindh    schedule 11.05.2020


Ответы (2)


Поскольку документ возвращается обработчиком get, а не обработчиком запроса, ваш индекс не обновляется должным образом после индексации документа.

Как вы сами заметили, в своей конфигурации вы установили:

"index.refresh_interval" => -1

.. что означает, что индекс не обновляется автоматически. Редко возникает необходимость изменять интервал обновления, за исключением ситуаций с очень высокой пропускной способностью или когда требуется определенное поведение.

person MatsLindh    schedule 11.05.2020

Попробуйте проиндексировать документ примерно так.

$client = Elasticsearch\ClientBuilder::create()
                    ->setHosts($hosts)
                    ->build();

$params = [
    'index' => 'elasticindex',
    'type' => 'documents',
    'id' => '1',
    'body' => ['text' => 'apple']
];

$response = $client->index($params);
print_r($response);

Примечание: _id вы можете определить динамически, если хотите, иначе id будет автоматически установлен эластичным.

И попробуйте получить документ по поисковому запросу.

{
    "query": {
        "bool": {
            "must": {
                "term": {
                    "text": "apple"
                }
            }
        }
    }
}

Если вы хотите полнотекстовый поиск по этому ключу, установите это свойство ключа как

"properties": {
   "name": {
     "type": "text"
   }
}
person jithu thomas    schedule 10.05.2020
comment
Я пробовал, как ты сказал. Я получил такой же пустой ответ. Кроме того, типы сопоставления были удалены в elasticsearch 7.0 sp, это не будет работать в версии, которую я использую 'type' = ›'documents', - person Mohamed Abdullah; 11.05.2020
comment
Вы уверены, что ваш документ создается правильно? попробуйте получить на основе _id и проверьте ключ text, присутствующий в любом из документов - person jithu thomas; 11.05.2020