void WordMatchSearchImpl::query(const QString &req, QVector<Service::Item *> *res) const { QSet<Service::Item*>* resSet = nullptr; QStringList words = req.split(' ', QString::SkipEmptyParts); // Quit if there are no words in query if (words.empty()) return; for (QString &w : words) { InvertedIndex::const_iterator lb, ub; lb = std::lower_bound (_invertedIndex.cbegin(), _invertedIndex.cend(), w, CaseInsensitiveCompare()); ub = std::upper_bound (_invertedIndex.cbegin(), _invertedIndex.cend(), w, CaseInsensitiveComparePrefix()); QSet<Service::Item*> tmpSet; while (lb!=ub) tmpSet.unite(lb++->second); if (resSet == nullptr) resSet = new QSet<Service::Item*>(tmpSet); else resSet->intersect(tmpSet); } if (resSet != nullptr) { for (Service::Item *s : *resSet) res->append(s); delete resSet; } }
void FuzzySearchImpl::buildIndex() { _invertedIndex.clear(); _qGramIndex.clear(); // Build inverted index for (Service::Item *item : _indexRef) { QStringList words = item->title().split(QRegExp("\\W+"), QString::SkipEmptyParts); for (QString &w : words) _invertedIndex[w.toLower()].insert(item); } // Build qGramIndex for (InvertedIndex::const_iterator it = _invertedIndex.cbegin(); it != _invertedIndex.cend(); ++it) { //Split the word into lowercase qGrams QString spaced = QString(_q-1,' ').append(it.key().toLower()); for (unsigned int i = 0 ; i < static_cast<unsigned int>(it.key().size()); ++i) // Increment #occurences of this qGram in this word ++_qGramIndex[spaced.mid(i,_q)][it.key()]; } }