Last active
June 22, 2020 06:28
-
-
Save balvinder294/c1a70177055a45c927dd3500e3cb3f17 to your computer and use it in GitHub Desktop.
Method to modify elasticsearch query to get score using hits from query response with elasticsearch spring boot.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/***** | |
* Tekraze.com for more | |
* | |
*****/ | |
///Imports | |
import org.springframework.data.domain.Page; | |
import org.springframework.data.domain.PageImpl; | |
import org.springframework.data.domain.PageRequest; | |
import org.springframework.data.domain.Pageable; | |
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; | |
import org.springframework.data.elasticsearch.core.ResultsExtractor; | |
import org.springframework.data.elasticsearch.core.query.*; | |
import org.elasticsearch.search.SearchHit; | |
import org.elasticsearch.action.search.SearchResponse; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; | |
import static org.elasticsearch.index.query.QueryBuilders.*; | |
/** | |
* Method to modify query and get Hit Score, and total hits to get a match score | |
* Instead of BookDTO , you can replace with your class | |
* | |
* @param query is any query like match query, bool query | |
* @param the pageable paramter containing pagination properies like page size, page number | |
**/ | |
Page<BookDTO> bookPage(QueryBuilder query, Pageable pageable) { | |
/*We create a query with rquired properties */ | |
SearchQuery searchQuery = new NativeSearchQueryBuilder() | |
.withQuery(query) // wrap the query we created like match query | |
.withPageable(pageable) // if pagination required | |
.withIndices(bookIndexName) // rquired name of index to search | |
.withTrackScores(true) // required to get hits and total hits | |
.build(); | |
// THe main logic, it is to modify the results and get hits | |
// extracting from response object | |
Page<BookDTO> result = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Page<BookDTO>>() { | |
@Override | |
public Page<BookDTO> extract(SearchResponse response) { | |
List<BookDTO> bookList = new LinkedList<BookDTO>(); | |
// Modify DTO from helper method with score | |
response.getHits().forEach(hit -> bookList.add(bookDTOFromMap(hit, response))); | |
// return page of recordds with score as nested property of DTO | |
return new PageImpl<BookDTO>(bookList, pageable, response.getHits().getTotalHits()); | |
} | |
}); | |
return result; | |
} | |
/**** | |
**Helper method to get Matchh Score from Hits and total hits | |
** and append to the DTO propeerty/ | |
****/ | |
BookDTO bookDTOFromMap(SearchHit hit, SearchResponse searchResponse) { | |
log.debug("Method to get Book DTO from Book Map"); | |
// Mapper to map hit object our DDTO | |
ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule()); | |
BookDTO bookDTO = objectMapper.convertValue(hit.getSourceAsMap(), BookDTO.class); | |
// The score calculate function | |
BigDecimal matchPercentage = new BigDecimal((hit.getScore() / searchResponse.getHits().getMaxScore()) * 100) | |
.setScale(2, RoundingMode.UP); | |
// set the score to DTO property | |
bookDTO.setMatchPercentage(matchPercentage); | |
return bookDTO; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment