[search] Match keywords to category types.

This commit is contained in:
Yury Melnichek 2011-07-04 18:22:49 +02:00 committed by Alex Zolotarev
parent 6d41d856db
commit c53771a6cd
2 changed files with 57 additions and 26 deletions

View file

@ -6,6 +6,7 @@
#include "../indexer/feature_visibility.hpp"
#include "../base/exception.hpp"
#include "../base/stl_add.hpp"
#include "../std/algorithm.hpp"
#include "../std/scoped_ptr.hpp"
namespace search
@ -117,6 +118,10 @@ Query::Query(string const & query, m2::RectD const & viewport, IndexType const *
m_prefix.swap(m_keywords.back());
m_keywords.pop_back();
}
ASSERT_LESS_OR_EQUAL(m_keywords.size(), 31, ());
if (m_keywords.size() > 31)
m_keywords.resize(31);
}
Query::~Query()
@ -127,6 +132,9 @@ Query::~Query()
void Query::Search(function<void (Result const &)> const & f)
{
if (m_bTerminate)
return;
// Lat lon matching.
{
double lat, lon, latPrec, lonPrec;
@ -143,39 +151,60 @@ void Query::Search(function<void (Result const &)> const & f)
// Category matching.
if (m_pCategories)
{
for (int i = 0; i < m_keywords.size(); ++i)
for (CategoriesHolder::const_iterator iCategory = m_pCategories->begin();
iCategory != m_pCategories->end(); ++iCategory)
{
string bestPrefixMatch;
// TODO: Use 1 here for exact match?
static int const PREFIX_LEN_BITS = 5;
int bestPrefixMatchPenalty =
((GetMaxPrefixMatchScore(m_prefix.size()) + 1) << PREFIX_LEN_BITS) - 1;
}
// TODO: Check if some keyword matched category?
if (!m_prefix.empty())
{
for (CategoriesHolder::const_iterator iCategory = m_pCategories->begin();
iCategory != m_pCategories->end(); ++iCategory)
for (vector<Category::Name>::const_iterator iName = iCategory->m_synonyms.begin();
iName != iCategory->m_synonyms.end(); ++iName)
{
KeywordMatcher matcher = MakeMatcher(vector<strings::UniString>(), m_prefix);
for (vector<Category::Name>::const_iterator iName = iCategory->m_synonyms.begin();
iName != iCategory->m_synonyms.end(); ++iName)
if (!m_keywords.empty())
{
// TODO: Insert spelling here?
vector<strings::UniString> tokens;
SplitAndNormalizeAndSimplifyString(iName->m_name, MakeBackInsertFunctor(tokens),
Delimiters());
int const n = tokens.size();
if (m_keywords.size() >= n)
{
if (equal(tokens.begin(), tokens.end(), m_keywords.begin()))
for (vector<uint32_t>::const_iterator iType = iCategory->m_types.begin();
iType != iCategory->m_types.end(); ++iType)
m_keywordsToSkipForType[*iType] |= (1 << n) - 1;
if (equal(tokens.begin(), tokens.end(), m_keywords.end() - n))
for (vector<uint32_t>::const_iterator iType = iCategory->m_types.begin();
iType != iCategory->m_types.end(); ++iType)
m_keywordsToSkipForType[*iType] |= ((1 << n) - 1) << (m_keywords.size() - n);
}
}
else if (!m_prefix.empty())
{
// TODO: Prefer user languages here.
if (m_prefix.size() >= iName->m_prefixLengthToSuggest)
matcher.ProcessNameToken(iName->m_name, strings::MakeUniString(iName->m_name));
{
KeywordMatcher matcher = MakeMatcher(vector<strings::UniString>(), m_prefix);
matcher.ProcessNameToken(string(), NormalizeAndSimplifyString(iName->m_name));
ASSERT_LESS(iName->m_prefixLengthToSuggest, 1 << PREFIX_LEN_BITS, ());
int const penalty =
(matcher.GetPrefixMatchScore() << PREFIX_LEN_BITS) + iName->m_prefixLengthToSuggest;
if (penalty < bestPrefixMatchPenalty)
{
bestPrefixMatchPenalty = penalty;
bestPrefixMatch = iName->m_name;
}
}
}
}
if (matcher.GetPrefixMatchScore() <= GetMaxPrefixMatchScore(m_prefix.size()) &&
matcher.GetMatchScore() <= GetMaxKeywordMatchScore())
{
int minPrefixMatchLength = 0;
for (vector<Category::Name>::const_iterator iName = iCategory->m_synonyms.begin();
iName != iCategory->m_synonyms.end(); ++iName)
if (iName->m_name == matcher.GetBestMatchName())
minPrefixMatchLength = iName->m_prefixLengthToSuggest;
AddResult(IntermediateResult(matcher.GetBestMatchName(),
matcher.GetBestMatchName() + ' ',
minPrefixMatchLength));
}
if (!bestPrefixMatch.empty())
{
AddResult(IntermediateResult(bestPrefixMatch, bestPrefixMatch + ' ',
bestPrefixMatchPenalty));
}
}
}

View file

@ -10,6 +10,7 @@
#include "../std/queue.hpp"
#include "../std/scoped_ptr.hpp"
#include "../std/string.hpp"
#include "../std/unordered_map.hpp"
#include "../std/vector.hpp"
namespace search
@ -56,6 +57,7 @@ private:
CategoriesHolder * m_pCategories;
vector<strings::UniString> m_keywords;
unordered_map<uint32_t, uint32_t> m_keywordsToSkipForType;
vector<vector<uint32_t> > m_keywordCategories;
strings::UniString m_prefix;