Я серьезно борюсь с запросом в эластичном поиске, поэтому надеюсь, что кто-то здесь может мне помочь.
Итак, у меня есть индекс в эластичном поиске, который хранит некоторую базовую информацию о пользователе. Затем у меня есть Spring Boot API, который позволяет клиенту выполнять поиск по указанному индексу.
В моем приложении, когда пользователь регистрируется, он может выбрать отображаемое имя на сайте. Теперь, когда они вводят отображаемое имя, я хочу иметь возможность проверить эластичность и сказать им, занято оно или нет.
Однако я борюсь, скажем, у меня есть один пользователь в моем индексе с DisplayName «John Boy», теперь пользователь два регистрируется и хочет отображаемое имя «Boy». Когда я провожу поиск, чтобы увидеть, не было ли занято «Boy», я возвращаю «John Boy». Я хочу, чтобы запрос подсказывал мне, свободен ли «Мальчик», и не заботился о том, был ли взят «Мальчик Джон».
Я думал, что просто разбираюсь в ES, но, может быть, нет, у меня создалось впечатление, что ключевое слово поля (см. Сопоставление индекса ниже) я могу выполнить поиск по термину и получить точное совпадение?
Ниже я включил свой Pojo и свое отображение индекса ES. Пожалуйста, если кто-нибудь может мне помочь .... спасибо за чтение:
Метод поиска
public long checkUserNameAvailability(String query) {
QueryBuilder matchSpecificFieldQuery= QueryBuilders
.termQuery("displayName", query);
Query searchQuery = new NativeSearchQueryBuilder()
.withFilter(matchSpecificFieldQuery)
.build();
SearchHits<UserProfile> searchSuggestions =
elasticsearchOperations.search(searchQuery,
UserProfile.class,
IndexCoordinates.of(elasticUserIndex));
List<UserProfile> suggestions = new ArrayList<>();
return searchSuggestions.getTotalHits();
}
Pojo
@Getter
@Setter
@Document(indexName = "userprofiles")
public class UserProfile {
@Field(type = FieldType.Text, name = "userId")
private String userId;
@Field(type = FieldType.Keyword, name = "displayName")
private String displayName;
@Field(type = FieldType.Text, name = "name")
private String name;
}
ES Mapping
{
"userprofiles": {
"mappings": {
"properties": {
"displayName": {
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"type": "text"
},
"name": {
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"type": "text"
},
"userId": {
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"type": "text"
}
}
}
}
}
Примечание: Я использую Spring загрузочную версию 2.4.3
А также
compile('org.springframework.boot:spring-boot-starter-data-elasticsearch')
compile group: 'org.springframework.data', name: 'spring-data-elasticsearch', version: '4.1.5'
Еще раз большое спасибо




Я думаю, вам следует подумать о том, какой тип запроса вы используете. Попробуйте использовать простое соответствие в поле .keyword.
Не могу поблагодарить тебя, Матаб, я честно сходил с ума
Возможно, вам стоит использовать запрос по ключевым словам, поскольку тип поля displayName является текстовым, он будет анализатором как в запросе, так и в индексе.
QueryBuilder matchSpecificFieldQuery= QueryBuilders
.termQuery("displayName.keyword", query);
Отлично, спасибо! Есть ли способ сделать термин запрос нечувствительным к регистру?
Хорошо, я воссоздал свой индекс, чтобы установить "normalizer": "case_insensitive_normalizer", а затем выполнил запрос соответствия, и теперь он работает, как ожидалось. Не могу отблагодарить вас за помощь
привет, интересно, возможно, может помочь запрос точное совпадение вместо запроса термина