Reputation: 1926
i have a searchfield on my page and this searchfield should search over more than one indice. I can search for one indice without a problem, like described in the documentation of spring-data-elasticsearch.
But if i search, as example for "Foo", i want to have the following list as result ordered by relevance:
{ title: "Foo" } -> Entity: Sample
{ name: "FooTest" } -> Entity: Test
{ title: "FooSample2" } -> Entity: Sample
// ...and so on
// The entities are not part of the same parent. So, they are complete different.
For this i couldn't find anything in documentation that would help me.
can anybody help?
EDIT:
final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchAllQuery())
.withIndices("game-index", "lets-play-index", "video-index", "genre-index", "platform-index", "user-index")
.withPageable(new PageRequest(0, 10))
.build();
// when
final Page<SearchResult> sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SearchResult.class, new SearchResultMapper() {
@Override
public <T> FacetedPage<T> mapResults(
final SearchResponse response,
final Class<T> clazz,
final Pageable pageable) {
LoggerUtil.get(this.getClass())
.debug(response.toString());
LoggerUtil.get(this.getClass())
.debug(response.getHits()
.toString());
LoggerUtil.get(this.getClass())
.debug("TotalHits: " + response.getHits()
.totalHits());
final long totalHits = response.getHits()
.totalHits();
final List<T> results = new ArrayList<T>();
for (final SearchHit hit : response.getHits()) {
LoggerUtil.get(this.getClass())
.debug(hit.sourceAsString());
if (hit != null) {
final T result = null;
/*
* if (!Strings.isNullOrEmpty(hit.sourceAsString()))
* { result = mapEntity(hit.sourceAsString(),
* clazz); } else { result =
* mapEntity(hit.getFields() .values(), clazz); }
*/
// setPersistentEntityId(result, hit.getId(),
// clazz);
results.add(result);
}
}
final List<FacetResult> facets = new ArrayList<FacetResult>();
if (response.getFacets() != null) {
for (final Facet facet : response.getFacets()) {
final FacetResult facetResult = DefaultFacetMapper.parse(facet);
if (facetResult != null) {
facets.add(facetResult);
}
}
}
return new FacetedPageImpl<T>(results, pageable, totalHits, facets);
}
});
the response inside of SearchResultMapper is the follwing:
{
"took" : 5,
"timed_out" : false,
"_shards" : {
"total" : 30,
"successful" : 30,
"failed" : 0
},
"hits" : {
"total" : 0,
"max_score" : null,
"hits" : [ ]
}
}
if i do a simple search with this:
final Class<?> clazz = Class.forName(className);
final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(getQueryBuilderForQuery(query))
.build();
final List<?> results = elasticsearchTemplate.queryForList(searchQuery, clazz);
it works and i get many results. that means my index is working.
i have definitly no idea what i can do. thanks a lot.
Upvotes: 5
Views: 7798
Reputation: 1008
Sorry this is already supported
try below code, it should be working...
however below code is for where you have same structure in Entity and elasticsearch document
@Test
public void shouldTestResultsAcrossMultipleIndices() {
// given
String documentId1 = randomNumeric(5);
SampleEntity sampleEntity1 = new SampleEntityBuilder(documentId1).message("some message")
.version(System.currentTimeMillis()).build();
IndexQuery indexQuery1 = new IndexQueryBuilder().withId(sampleEntity1.getId())
.withIndexName("test-index-1")
.withObject(sampleEntity1)
.build();
String documentId2 = randomNumeric(5);
SampleEntity sampleEntity2 = new SampleEntityBuilder(documentId2).message("some test message")
.version(System.currentTimeMillis()).build();
IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId())
.withIndexName("test-index-2")
.withObject(sampleEntity2)
.build();
elasticsearchTemplate.bulkIndex(Arrays.asList(indexQuery1, indexQuery2));
elasticsearchTemplate.refresh("test-index-1", true);
elasticsearchTemplate.refresh("test-index-2", true);
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(matchAllQuery())
.withIndices("test-index-1", "test-index-2")
.build();
// when
List<SampleEntity> sampleEntities = elasticsearchTemplate.queryForList(searchQuery, SampleEntity.class);
// then
assertThat(sampleEntities.size(), is(equalTo(2)));
}
if you have different structure in the index then you can use below method of elasticsearchTemplate
Page<T> queryForPage(SearchQuery query, Class<T> clazz, SearchResultMapper mapper);
still confused ? happy to help :-)
Upvotes: 5