Добрый день! Только начал работать с эластиком. Проблема в том, что поиск не возвращает все варианты. Я так понимаю дело в том, что у меня не настроен анализатор russian (https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-lang-analyzer.html#russian- analyzer)
Но у меня не получается его настроить.. Прошу помочь тем, кто в курсе как это сделать. Вот код создания индекса и наполнения его данными для поиска из БД:
require 'vendor/autoload.php';
$client = \Elasticsearch\ClientBuilder::create()->setHosts([ES_HOST])->build();
$params = [];
$params['index'] = ES_INDEX;
//Удаляю индекс
if($client->indices()->exists($params)){
$response = $client->indices()->delete($params);
}
//Создаю запись
if(! $client->indices()->exists($params)){
$index = $client->index([
'index' => ES_INDEX,
'type' => ES_TYPE,
'id' => ES_ID,
'body' => []
]);
}
$sql = "SELECT id, `name` FROM salons_services";
$result = $conn->query($sql);
//Заполняю индекс значениями для поиска
foreach ($result as $row) {
$params['body'][] = [
'index' => [
'_index' => ES_INDEX,
'_type' => ES_TYPE,
]
];
$params['body'][] = [
'tableid' => $row['id'],
'tablename' => trim($row['name'])
];
}
$responses = $client->bulk($params);
А потом этой функцией ищу IDники по слову
function searchES($word) {
$client = \Elasticsearch\ClientBuilder::create()->setHosts([ES_HOST])->build();
$IDs = [];
$params = [];
$params['index'] = ES_INDEX;
if ($client->indices()->exists($params)) {
$params['type'] = ES_TYPE;
$params['body']['query']['match']['tablename'] = trim($word);
$result = $client->search($params);
if ($result['hits']['total'] > 0) {
$result = $result['hits']['hits'];
foreach ($result as $val) {
$k = $val['_source']['tableid'];
$IDs[$k] = $k;
}
}
}
return $IDs;
}
Вот как я и сказал - возвращаются не все результаты... Я думаю, что надо подключить анализатор. Кто может подсказать, как это сделать? Заранее спасибо!
При создании индекса нужно добавить маппинг, вот так:
$config = [
'index' => 'my_index',
'type' => 'my_type'
];
$client = Elasticsearch\ClientBuilder::create()->build();
if ($client->indices()->exists(['index' => $config['index']]) ) {
$result = $client->indices()->delete(['index' => $config['index']]);
}
$params = [
'index' => $config['index'],
'body' => [
'settings' => [
'number_of_shards' => 1,
'number_of_replicas' => 1
],
'mappings' => [
$config['type'] => [
'_source' => [
'enabled' => true
],
'properties' => [
'tableid' => [
'type' => 'integer'
],
'tablename' => [
'type' => 'string',
'analyzer' => 'russian'
]
]
]
]
]
];
$result = $client->indices()->create($params);
Заполним тестовыми данными
$result = $client->indices()->create($params);
$fixtures = [
['id' => 1, 'name' => 'На дворе трава'],
['id' => 3, 'name' => 'На траве дрова'], ];
$bulkData = ['body' => []];
foreach ($fixtures as $row) {
$bulkData['body'][] = [
'index' => [
'_index' => $config['index'],
'_type' => $config['type'],
'_id' => $row['id']
]
];
$bulkData['body'][] = [
'tableid' => $row['id'],
'tablename' => trim($row['name'])
]; }
$responses = $client->bulk($bulkData);
Пробуем найти по запросу "трава"
$word = 'трава';
$client = Elasticsearch\ClientBuilder::create()->build();
$params = [
'index' => $config['index'],
'type' => $config['type'],
'body' => [
'query' => [
'match' => [
'tablename' => $word
]
]
]
];
$result = $client->search($params);
$ids = [];
if ($result['hits']['total'] > 0) {
$result = $result['hits']['hits'];
foreach ($result as $val) {
array_push($ids, $val['_source']['tableid']);
}
}
print_r($ids);
Видим результат:
Array
(
[0] => 1
[1] => 3
)
Как видно, предложение со склоненным словом траве корректно нашлось.
Очень часто встроенного анализатора russian бывает мало и стоит присмотреться к плагину elasticsearch-analysis-morphology
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости