diff --git a/include/searcher.h b/include/searcher.h index 89787873b..e5549778f 100644 --- a/include/searcher.h +++ b/include/searcher.h @@ -61,6 +61,7 @@ class Searcher unsigned int resultStart, unsigned int resultEnd, const bool verbose = false); + void suggestions(std::string& search, const bool verbose = false); Result* getNextResult(); void restart_search(); unsigned int getEstimatedResultCount(); diff --git a/src/reader.cpp b/src/reader.cpp index c967b2473..914f88c50 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -20,6 +20,8 @@ #include "reader.h" #include +#include + inline char hi(char v) { char hex[] = "0123456789abcdef"; @@ -678,11 +680,29 @@ bool Reader::searchSuggestionsSmart(const string& prefix, this->suggestions.clear(); this->suggestionsOffset = this->suggestions.begin(); - for (std::vector::iterator variantsItr = variants.begin(); - variantsItr != variants.end(); - variantsItr++) { - retVal = this->searchSuggestions(*variantsItr, suggestionsCount, false) - || retVal; + /* Try to search in the title using fulltext search database */ + const zim::Search* suggestionSearch + = this->getZimFileHandler()->suggestions(prefix, 0, suggestionsCount); + + if (suggestionSearch->get_matches_estimated()) { + for (auto current = suggestionSearch->begin(); + current != suggestionSearch->end(); + current++) { + std::vector suggestion; + suggestion.push_back(current->getTitle()); + suggestion.push_back("/A/" + current->getUrl()); + suggestion.push_back(kiwix::normalize(current->getTitle())); + this->suggestions.push_back(suggestion); + } + this->suggestionsOffset = this->suggestions.begin(); + retVal = true; + } else { + for (std::vector::iterator variantsItr = variants.begin(); + variantsItr != variants.end(); + variantsItr++) { + retVal = this->searchSuggestions(*variantsItr, suggestionsCount, false) + || retVal; + } } return retVal; diff --git a/src/searcher.cpp b/src/searcher.cpp index 5c4074f34..4bfeab355 100644 --- a/src/searcher.cpp +++ b/src/searcher.cpp @@ -172,6 +172,31 @@ void Searcher::reset() return; } +void Searcher::suggestions(std::string& search, const bool verbose) +{ + this->reset(); + + if (verbose == true) { + cout << "Performing suggestion query `" << search << "`" << endl; + } + + this->searchPattern = search; + this->resultStart = 0; + this->resultEnd = 10; + string unaccentedSearch = removeAccents(search); + + if (internal->_xapianSearcher) { + /* [TODO] Suggestion on a external database ? + * We do not support that. */ + this->estimatedResultCount = 0; + } else { + internal->_search = this->reader->getZimFileHandler()->suggestions( + unaccentedSearch, resultStart, resultEnd); + internal->current_iterator = internal->_search->begin(); + this->estimatedResultCount = internal->_search->get_matches_estimated(); + } +} + /* Return the result count estimation */ unsigned int Searcher::getEstimatedResultCount() {