Skip to content

Instantly share code, notes, and snippets.

@balvinder294
Last active June 22, 2020 06:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save balvinder294/c1a70177055a45c927dd3500e3cb3f17 to your computer and use it in GitHub Desktop.
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.
/*****
* 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