#java #spring #spring-boot #elasticsearch #spring-data
Вопрос:
Я искал ответ повсюду и, похоже, ничего не нашел, поэтому приношу извинения, если об этом спрашивали раньше.
У меня есть простой API Spring boot, который позволяет студентам добавлять свои проекты в колледже. Эти проекты хранятся в ES, которые я пытаюсь сделать доступными для поиска.
FWIW, В примере использования POV пользователь может искать проект с помощью строки запроса, основанной на имени проекта или хэштеге для проекта, т. е. «Java».
Прямо сейчас с помощью приведенного ниже кода, если я буду искать проекты с заданным хэштегом, я без проблем смогу их получить. Я получаю именно те результаты, которые ищу.
Однако…как только я попытаюсь добавить второй запрос, в котором я хочу ограничить результаты только студентами, у которых идентификатор пользователя содержится в списке ArrayList, мой поиск завершится неудачей. Под неудачами я подразумеваю, что он возвращает все из индекса.
Кто-нибудь может определить, что я делаю не так?
Большое спасибо
private Iterable<UserProjects> searchCollegeProjects(Integer page, Integer size, List<String> hashtags, List<String> studentUserIds) {
PageRequest pageRequest = PageRequest.of(page, size);
QueryBuilder projectQueryBuilder = null;
if (hashtags != null) {
projectQueryBuilder =
QueryBuilders
.multiMatchQuery(hashtags.toString(), "projectName", "projectHashtag")
.fuzziness(Fuzziness.AUTO);
}
BoolQueryBuilder userIdQueryBuilder = null;
if(studentUserIds!=null) {
userIdQueryBuilder = QueryBuilders.boolQuery()
.must(QueryBuilders.termsQuery("userId.keyword", studentUserIds));
}
Query searchQuery = new NativeSearchQueryBuilder()
.withQuery(projectQueryBuilder)
.withQuery(userIdQueryBuilder)
.withFilter(boolQuery()
.mustNot(QueryBuilders.termsQuery("isDraft", true)))
.withPageable(PageRequest.of(page, size))
.build();
SearchHits<UserProjects> projectHits;
try {
projectHits =
elasticsearchOperations
.search(searchQuery, UserProjects.class,
IndexCoordinates.of(elasticProjectsIndex));
} catch (Exception ex) {
logger.error("Error unable to perform search query" ex);
throw new GeneralSearchException(ex.toString());
}
List<UserProjects> projectMatches = new ArrayList<>();
projectHits.forEach(srchHit -> {
projectMatches.add(srchHit.getContent());
});
long totalCount = projectHits.getTotalHits();
Page<UserProjects> resultPage = PageableExecutionUtils.getPage(
projectMatches,
pageRequest,
() -> totalCount);
return resultPage;
}
Также ниже приведен мой POJO для пользовательских проектов:
@Getter
@Setter
@Document(indexName = "college.userprojects")
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserProjects {
@Id
@Field(type = FieldType.Auto, name ="_id")
private String projectId;
@Field(type = FieldType.Text, name = "userId")
private String userId;
@Field(type = FieldType.Text, analyzer = "autocomplete_index", searchAnalyzer = "lowercase" ,name = "projectName")
private String projectName;
@Field(type = FieldType.Auto, name = "projectHashTag")
private List<String> projectHashTag;
@Field(type = FieldType.Boolean, name = "isDraft")
private Boolean isDraft;
}
EDIT: Just to be clear, if I remove this line from the native query:
.withQuery(userIdQueryBuilder)
Я возвращаю проекты (правильно), которые содержат текст запроса в полях Имя проекта или Хэштег проекта. Если вставить приведенную выше строку обратно, поиск вернет все.