Suggestions now use xapian database when available.

If a embedded fulltext database is present, suggestion will search in it :
 - insensitive case search.
 - search for terms in the middle of the title.
 - xapian will try to complete the last word of the query (as if a '*'
   were added at the end)
This commit is contained in:
Matthieu Gautier 2017-07-11 17:13:21 +02:00
parent 57720ca57b
commit d0371cd133
3 changed files with 51 additions and 5 deletions

View File

@ -61,6 +61,7 @@ class Searcher
unsigned int resultStart, unsigned int resultStart,
unsigned int resultEnd, unsigned int resultEnd,
const bool verbose = false); const bool verbose = false);
void suggestions(std::string& search, const bool verbose = false);
Result* getNextResult(); Result* getNextResult();
void restart_search(); void restart_search();
unsigned int getEstimatedResultCount(); unsigned int getEstimatedResultCount();

View File

@ -20,6 +20,8 @@
#include "reader.h" #include "reader.h"
#include <time.h> #include <time.h>
#include <zim/search.h>
inline char hi(char v) inline char hi(char v)
{ {
char hex[] = "0123456789abcdef"; char hex[] = "0123456789abcdef";
@ -678,12 +680,30 @@ bool Reader::searchSuggestionsSmart(const string& prefix,
this->suggestions.clear(); this->suggestions.clear();
this->suggestionsOffset = this->suggestions.begin(); this->suggestionsOffset = this->suggestions.begin();
/* 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<std::string> 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<std::string>::iterator variantsItr = variants.begin(); for (std::vector<std::string>::iterator variantsItr = variants.begin();
variantsItr != variants.end(); variantsItr != variants.end();
variantsItr++) { variantsItr++) {
retVal = this->searchSuggestions(*variantsItr, suggestionsCount, false) retVal = this->searchSuggestions(*variantsItr, suggestionsCount, false)
|| retVal; || retVal;
} }
}
return retVal; return retVal;
} }

View File

@ -172,6 +172,31 @@ void Searcher::reset()
return; 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 */ /* Return the result count estimation */
unsigned int Searcher::getEstimatedResultCount() unsigned int Searcher::getEstimatedResultCount()
{ {