I'm implementing custom repository based on Spring Data Elasticsearch:
@Document(indexName = "product", createIndex = false)
public class ProductDocument implements Serializable {
@Id
private String id;
@NotNull
private String name;
}
@Override
public List<ProductDocument> findByIdsAndName(List<String> productIds, String name) {
Query query = new NativeSearchQueryBuilder()
.withIds(productIds)
.withQuery(QueryBuilders.prefixQuery("name", name))
.build();
return operations.search(query, clazz, indexCoordinates)
.stream()
.map(SearchHit::getContent)
.collect(Collectors.toList());
}
The problem I'm facing is that the query is not working, e.g. I save into ES items like
productRepository.saveAll(Arrays.asList(
ProductDocument.builder().id("1").name("Pikachu1").build(),
ProductDocument.builder().id("2").name("Pikachu2").build(),
ProductDocument.builder().id("3").name("Pikachu3").build(),
ProductDocument.builder().id("4").name("Pikachu4").build(),
ProductDocument.builder().id("5").name("Pikachu5").build()
)
and then call the method
assertThat(productRepository.findByIdsAndName(List.of("1", "2"), "Pika")).hasSize(2);
repository method returns an empty list and assertion fails. I've also tried to implement query like
Query query = new NativeSearchQueryBuilder()
.withFilter(QueryBuilders.idsQuery().addIds(productIds.toArray(String[]::new)))
.withQuery(QueryBuilders.prefixQuery("name", name))
.build();
but it fails either. The problem seems to be about prefixQuery
because when I remove it the query works.
What am I doing wrong?
CodePudding user response:
Are you sure the id is the _id elasticsearch also searches for. It could be that it is a property of the document but the actual id is something else. I had this issue. So I stored a document with an id attribute but elasticsearch assigned an id itself which had nothing to do with the id of the document. Maybe try with postman or a restcall to check what exactly is inside elasticsearch after saveAll.
CodePudding user response:
I've found a work-around:
@Override
public List<ProductDocument> findByIdsAndName(Collection<String> productIds, String name) {
BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
queryBuilder.must(QueryBuilders.idsQuery().addIds(productIds.toArray(String[]::new)));
queryBuilder.must(QueryBuilders.matchBoolPrefixQuery("name", name));
Query query = new NativeSearchQueryBuilder().withQuery(queryBuilder).build();
return operations.search(query, clazz, indexCoordinates)
.stream()
.map(SearchHit::getContent)
.collect(Collectors.toList());
}
Still I think that this is a bug. I've filed an issue here: https://github.com/spring-projects/spring-data-elasticsearch/issues/2188
Let's wait for maintainer's response.