Получить Elasticsearch соответствия на основе списка значений - PullRequest
0 голосов
/ 03 сентября 2018

Я использую Logstash для ввода данных из моей базы данных в Elasticsearch. Для конкретного запроса SQL у меня есть один столбец, который извлекает значения в виде CSV, например «role1; role2; role3». Этот столбец индексируется как обычная строка в Elastic.

Проблема: Мне нужно сделать упругий запрос для этого поля на основе другого списка значений.

Например : на стороне java у меня есть коллекция со значениями: "role3", "role4", "role5" и на основании этого я должен получить все записи в Elastic, которые соответствуют " role3 "," role4 "или" role5 ".

В этом конкретном случае мои эластичные данные выглядят так:

"_source": {
  "userName": "user1",
  "roles": "role1;role2;role3"  
}
"_source": {
  "userName": "user2",
  "roles": "role7;role8;role9"  
}

В этом случае он должен вернуть запись для «user1», так как он получает совпадение для «role3».

Вопрос: Каков наилучший способ сделать это? Я могу сделать запрос, используя что-то вроде оператора LIKE для всех итенов моего списка Java:

//javaList collection has 3 items: "role3", "role4" and "role5"
for (String role: javaList) {
    query = QueryBuilders.boolQuery();
    query.should(QueryBuilders.wildcardQuery("roles", "*" + role + "*"));
    response = client.prepareSearch(indexName).setQuery(query).setTypes(type).execute().actionGet();
    hits = response.getHits();
}

И затем повторять каждый удар, но это звучит как очень плохое аппроксимация, потому что javaList может иметь более 20 итенов, что будет означать 20 запросов на эластичность.

Мне нужен способ сообщить об этом Эластику:

This is my list of roles, query internally and retrieve
only the records that matches at least one of those roles.

Для этого я понимаю, что не могу индексировать эти данные как строку? В идеале было бы иметь массив или что-то вроде этого ...

Как я могу сделать это наиболее эффективным способом?

1 Ответ

0 голосов
/ 04 сентября 2018

Определенно, вы не должны использовать подстановочный запрос в цикле. Это решение в конечном итоге продемонстрирует низкую производительность.

Поскольку поле roles является обычным текстовым полем, Elasticsearch разбивает значение "role1; role2; role3" на отдельные токены "role1", "role2" и "role3". Эта же операция применяется к поисковому запросу. Вы можете использовать простой запрос на совпадение со строкой запроса "role3; role4; role5" и получить удар из-за совпадения токена "role3".

Также вы можете индексировать поле roles как массив строк, и тот же запрос на совпадение будет работать.

...