ElasticSearch Java Api Query Builder
Я пытаюсь сделать запрос в ElasticSearch с определенным параметром, но много раз он не работает.
Существуют значения параметров, которые, когда они имеют определенные символы (простые, как заглавная буква), больше не работают.
Например, у меня есть 3 регистра с ключом field1 и значением hello123, Hello123 и HeLLo-123.
Первое работает, а остальное всегда терпит неудачу.
Кто-нибудь может мне помочь?
Это мой код и следующее исполнение:
logger.info("Testing queries");
TransportClient client = elasticSearchManager.getClient();
String[] values = {"hello123","Hello123","HeLLo-123"};
for (int i = 0; i < 3; i++) {
XContentBuilder jsonInsert = jsonBuilder().startObject();
jsonInsert.field("field1", values[i]);
jsonInsert.endObject();
IndexResponse responseDB = client.prepareIndex(index, "id").setSource(jsonInsert).get();
logger.info("response with value : "+values[i]+" => " + responseDB.getResult());
logger.info("*********************************************");
}
logger.info("VALUES INSERTED");
logger.info("***************");
logger.info("QUERIES");
for (int i = 0; i < 3; i++){
BoolQueryBuilder query = QueryBuilders.boolQuery()
.filter(QueryBuilders.termQuery("field1", values[i]));
SearchResponse response = client.prepareSearch(WIFI4EUOPConstants.indexSnippet).setQuery(query).get();
logger.info("field with value "+values[i]+" : ");
logger.info(response.toString());
logger.info("*********************************************");
}
Исполнение:
изображение результата выполнения
PD: Я заметил, что первый запрос с параметром hello123 также возвращает результат Hello123, это не должно быть так...
Кто-нибудь может мне помочь?
Спасибо
PD2 ОБНОВЛЕНИЕ
Я попытался создать отображение в индексе, а затем вставить данные, но это не работает для меня. Я прикрепляю файлы:
Код:
XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("properties")
.startObject("field1").field("type", "string").field("analyzer", "keyword").endObject()
.endObject().endObject();
client.admin().indices().prepareCreate(index).addMapping("id",mapping);
Следующее изображение является результатом загрузки URL индекса (который называется "фрагмент"):
Результат остается прежним.
Может кто-нибудь сказать мне, правильно ли я определяю отображение или я делаю неправильно?
Спасибо
2 ответа
Происходит то, что вы индексируете данные без создания индекса и указания точного отображения, которое вы хотите.
Elasticsearch сделает предположения на основе входных данных и создаст их для вас. Например, если мы индексируем ниже:
POST foo/bar/1
{
"key": "HeLLo-123"
}
Мы можем видеть, что asticsearch создал это:
{
"foo": {
"aliases": {},
"mappings": {
"bar": {
"properties": {
"key": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
},
"settings": {
"index": {
"creation_date": "1517863731064",
"number_of_shards": "5",
"number_of_replicas": "1",
"uuid": "iQzvEfU0Sli3c2LRC6gjyA",
"version": {
"created": "5030199"
},
"provided_name": "foo"
}
}
}
}
Вы можете видеть, что поле, которое я проиндексировал, указано как мультиполе. Тот, к которому вы обращаетесь, указан как text
который анализируется. key.keyword
поле для точных совпадений (термин запроса). Так что если вы ищете против key.keyword
В этом поле вы получите ожидаемые результаты, а еще лучше - создайте свой индекс и определите отображение так, как вы этого хотите, и не допускайте, чтобы asticsearch делал какие-либо предположения.
Ну наконец-то с помощью алки у меня есть следующее решение:
String sourcedef = "{\n" +
" \"id\" : {\n" +
" \"properties\" : { \n" +
" \"field1\" : { \"type\":\"keyword\"}\n" +
" } \n" +
" }\n" +
" }\n" +
" }\n" +
"}";
// Convert String to Map<String, Object>
Map<String, Object> source = Utils.fromJSON(sourcedef);
String type = "id";
String indexDefined = "newindex";
CreateIndexResponse response = client.admin().indices().prepareCreate(indexDefined).addMapping(type,source).execute().actionGet();
С помощью предыдущего кода мы создаем индекс с отображением. Мы определяем, что поле 'field1' будет иметь тип ключевого слова, которое будет точно соответствовать запросу, который мы поставили.
Затем, когда мы выполняем следующий код с помощью termQuery, он работает и хорошо фильтрует результаты:
BoolQueryBuilder query = QueryBuilders.boolQuery()
.filter(QueryBuilders.termQuery("field1", "definedvalue"));
SearchResponse response = client.prepareSearch(indexDefined).setQuery(query).get();
Надеюсь, поможет