use of org.eclipse.openvsx.search.RelevanceService.SearchStats in project openvsx by eclipse.
the class DatabaseSearchService method search.
@Cacheable("database.search")
public SearchHits<ExtensionSearch> search(ISearchService.Options options, Pageable pageRequest) {
// grab all extensions
var matchingExtensions = repositories.findAllActiveExtensions();
// no extensions in the database
if (matchingExtensions.isEmpty()) {
Aggregations aggregations = new Aggregations(Collections.emptyList());
return new SearchHitsImpl<ExtensionSearch>(0, TotalHitsRelation.OFF, 0f, "", Collections.emptyList(), aggregations);
}
// filter category
if (options.category != null) {
matchingExtensions = matchingExtensions.filter(extension -> extension.getLatest().getCategories().stream().anyMatch(category -> category.toLowerCase().equals(options.category.toLowerCase())));
}
// filter text
if (options.queryString != null) {
matchingExtensions = matchingExtensions.filter(extension -> extension.getName().toLowerCase().contains(options.queryString.toLowerCase()) || extension.getNamespace().getName().contains(options.queryString.toLowerCase()) || (extension.getLatest().getDescription() != null && extension.getLatest().getDescription().toLowerCase().contains(options.queryString.toLowerCase())) || (extension.getLatest().getDisplayName() != null && extension.getLatest().getDisplayName().toLowerCase().contains(options.queryString.toLowerCase())));
}
List<ExtensionSearch> sortedExtensions;
if ("relevance".equals(options.sortBy)) {
// for relevance we're using relevance service to get the relevance item
var searchStats = new SearchStats(repositories);
// needs to add relevance on extensions
sortedExtensions = new ArrayList<>(matchingExtensions.map(extension -> relevanceService.toSearchEntry(extension, searchStats)).toList());
// sort it
sortedExtensions.sort(new RelevanceComparator());
} else {
sortedExtensions = matchingExtensions.stream().map(extension -> extension.toSearch()).collect(Collectors.toList());
if ("downloadCount".equals(options.sortBy)) {
sortedExtensions.sort(new DownloadedCountComparator());
} else if ("averageRating".equals(options.sortBy)) {
sortedExtensions.sort(new AverageRatingComparator());
} else if ("timestamp".equals(options.sortBy)) {
sortedExtensions.sort(new TimestampComparator());
}
}
// 'asc' | 'desc';
if ("desc".equals(options.sortOrder)) {
// reverse the order
Collections.reverse(sortedExtensions);
}
// Paging
var totalHits = sortedExtensions.size();
if (pageRequest != null) {
var pageNumber = pageRequest.getPageNumber();
var pageSize = pageRequest.getPageSize();
var toSkip = 0;
if (pageNumber >= 1) {
// page is zero indexed
toSkip = pageNumber * (pageSize - 1) + pageNumber;
}
// if something to skip, remove the first elements
if (toSkip > 0 && toSkip < sortedExtensions.size()) {
sortedExtensions = sortedExtensions.subList(toSkip, sortedExtensions.size());
}
// keep only the pageSize elements
if (sortedExtensions.size() > pageSize) {
sortedExtensions = sortedExtensions.subList(0, pageSize);
}
}
List<SearchHit<ExtensionSearch>> searchHits;
if (sortedExtensions.isEmpty()) {
searchHits = Collections.emptyList();
} else {
// client is interested only in the extension IDs
searchHits = sortedExtensions.stream().map(extensionSearch -> {
return new SearchHit<ExtensionSearch>(null, null, 0.0f, Collections.emptyList().toArray(), Collections.emptyMap(), extensionSearch);
}).collect(Collectors.toList());
}
Aggregations aggregations = new Aggregations(Collections.emptyList());
SearchHits<ExtensionSearch> searchHitsResult = new SearchHitsImpl<ExtensionSearch>(totalHits, TotalHitsRelation.OFF, 0f, "", searchHits, aggregations);
return searchHitsResult;
}
Aggregations