diff --git a/generator/search_index_builder.cpp b/generator/search_index_builder.cpp index 104a4fce05..069ab4cdca 100644 --- a/generator/search_index_builder.cpp +++ b/generator/search_index_builder.cpp @@ -153,9 +153,13 @@ struct FeatureNameInserter m_keyValuePairs.emplace_back(key, m_val); } + // Adds search tokens for different ways of writing strasse: + // Hauptstrasse -> Haupt strasse, Hauptstr. + // Haupt strasse -> Hauptstrasse, Hauptstr. void AddStrasseNames(signed char lang, search::QueryTokens const & tokens) const { auto static const kStrasse = strings::MakeUniString("strasse"); + auto static const kStr = strings::MakeUniString("str"); for (size_t i = 0; i < tokens.size(); ++i) { auto const & token = tokens[i]; @@ -166,12 +170,16 @@ struct FeatureNameInserter if (token == kStrasse) { if (i != 0) + { AddToken(lang, tokens[i - 1] + kStrasse); + AddToken(lang, tokens[i - 1] + kStr); + } } else { auto const name = strings::UniString(token.begin(), token.end() - kStrasse.size()); AddToken(lang, name); + AddToken(lang, name + kStr); } } } diff --git a/search/ranker.cpp b/search/ranker.cpp index 74fbf02530..1149987bc6 100644 --- a/search/ranker.cpp +++ b/search/ranker.cpp @@ -55,35 +55,43 @@ void UpdateNameScores(vector const & tokens, Slice const & s bestScores.m_errorsMade = ErrorsMade::Min(bestScores.m_errorsMade, GetErrorsMade(tokens, slice)); } -// This function assumes that at most one token in |streetTokens| ends with "strasse". -bool ModifyStrasse(vector & streetTokens) +// This function supports only street names like "abcdstrasse"/"abcd strasse". +vector> ModifyStrasse(vector const & streetTokens) { + vector> result; auto static const kStrasse = strings::MakeUniString("strasse"); - for (size_t i = 0; i < streetTokens.size(); ++i) + auto static const kStr = strings::MakeUniString("str"); + auto const size = streetTokens.size(); + + if (size == 0 || !strings::EndsWith(streetTokens.back(), kStrasse)) + return {}; + + if (streetTokens.back() == kStrasse) { - auto & token = streetTokens[i]; - if (strings::EndsWith(token, kStrasse)) - { - if (token == kStrasse) - { - if (i != 0) - { - streetTokens[i - 1] = streetTokens[i - 1] + kStrasse; - streetTokens.erase(streetTokens.begin() + i); - return true; - } - } - else - { - streetTokens[i] = - strings::UniString(streetTokens[i].begin(), streetTokens[i].end() - kStrasse.size()); - streetTokens.insert(streetTokens.begin() + i + 1, kStrasse); - return true; - } - } + if (size == 1) + return {}; + + // "Abcd strasse" -> "abcdstrasse". + result.emplace_back(streetTokens.begin(), streetTokens.end() - 1); + result.back().back() += kStrasse; + + // "Abcd strasse" -> "abcdstr". + result.emplace_back(streetTokens.begin(), streetTokens.end() - 1); + result.back().back() += kStr; + return result; } - return false; + // "Abcdstrasse" -> "abcd strasse". + auto const name = + strings::UniString(streetTokens.back().begin(), streetTokens.back().end() - kStrasse.size()); + result.push_back(streetTokens); + result.back().back() = name; + result.back().push_back(kStrasse); + + // "Abcdstrasse" -> "abcdstr". + result.push_back(streetTokens); + result.back().back() = name + kStr; + return result; } NameScores GetNameScores(FeatureType & ft, Geocoder::Params const & params, @@ -111,10 +119,14 @@ NameScores GetNameScores(FeatureType & ft, Geocoder::Params const & params, UpdateNameScores(tokens, slice, bestScores); UpdateNameScores(tokens, sliceNoCategories, bestScores); - if (type == Model::TYPE_STREET && ModifyStrasse(tokens)) + if (type == Model::TYPE_STREET) { - UpdateNameScores(tokens, slice, bestScores); - UpdateNameScores(tokens, sliceNoCategories, bestScores); + auto const variants = ModifyStrasse(tokens); + for (auto const & variant : variants) + { + UpdateNameScores(variant, slice, bestScores); + UpdateNameScores(variant, sliceNoCategories, bestScores); + } } } diff --git a/search/search_integration_tests/processor_test.cpp b/search/search_integration_tests/processor_test.cpp index 2ed013f72d..8b830efbe8 100644 --- a/search/search_integration_tests/processor_test.cpp +++ b/search/search_integration_tests/processor_test.cpp @@ -1993,6 +1993,8 @@ UNIT_CLASS_TEST(ProcessorTest, Strasse) Rules rules = {ExactMatch(countryId, s1)}; checkNoErrors("abcdstrasse ", rules); checkNoErrors("abcdstrasse", rules); + checkNoErrors("abcdstr ", rules); + checkNoErrors("abcdstr", rules); checkNoErrors("abcdstraße ", rules); checkNoErrors("abcdstraße", rules); checkNoErrors("abcd strasse ", rules); @@ -2006,6 +2008,8 @@ UNIT_CLASS_TEST(ProcessorTest, Strasse) Rules rules = {ExactMatch(countryId, s2)}; checkNoErrors("xyzstrasse ", rules); checkNoErrors("xyzstrasse", rules); + checkNoErrors("xyzstr ", rules); + checkNoErrors("xyzstr", rules); checkNoErrors("xyzstraße ", rules); checkNoErrors("xyzstraße", rules); checkNoErrors("xyz strasse ", rules);