Skip to content
This repository was archived by the owner on Mar 15, 2018. It is now read-only.

Commit 3baf01c

Browse files
author
Rob Hudson
committed
Boost on exact matches in all locales (bug 972039)
1 parent 1aabb50 commit 3baf01c

4 files changed

Lines changed: 44 additions & 5 deletions

File tree

mkt/search/filters.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ def filter_queryset(self, request, queryset, view):
5050
should.append(k(**{field: v}))
5151

5252
# Exact matches need to be queried against a non-analyzed field. Let's
53-
# do a term query on `name_sort` for an exact match against the app
53+
# do a term query on `name.raw` for an exact match against the app
5454
# name and give it a good boost since this is likely what the user
5555
# wants.
56-
should.append(query.Term(name_sort={'value': q, 'boost': 10}))
56+
should.append(query.Term(**{'name.raw': {'value': q, 'boost': 10}}))
5757

5858
if analyzer:
5959
should.append(

mkt/search/tests/test_views.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,28 @@ def test_name_localized_to_default_locale(self):
536536
eq_(obj['slug'], self.webapp.app_slug)
537537
eq_(obj['name'], u'Algo Algo Steamcube!')
538538

539+
def test_name_localized_exact_match(self):
540+
other_apps = [app_factory(), app_factory()]
541+
other_apps[0].name = {'en-US': 'Spanish Tests',
542+
'es': 'Pruebas de Español'}
543+
other_apps[1].name = {'en-US': 'Tests in Spanish',
544+
'es': 'Pruebas en Español'}
545+
for app in other_apps:
546+
app.save()
547+
self.refresh('webapp')
548+
549+
res = self.anon.get(self.url, data={'q': 'Pruebas en Español',
550+
'lang': 'es'})
551+
eq_(res.status_code, 200)
552+
553+
# Ensure the exact matched name is first.
554+
obj = res.json['objects'][0]
555+
eq_(obj['id'], other_apps[1].id)
556+
557+
for app in other_apps:
558+
app.delete()
559+
unindex_webapps([app.pk for app in other_apps])
560+
539561
def test_author(self):
540562
res = self.anon.get(self.url,
541563
data={'author': self.webapp.developer_name})

mkt/webapps/indexers.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,23 @@ def _locale_field_mapping(field, analyzer):
133133
'manifest_url': cls.string_not_analyzed(),
134134
'modified': {'format': 'dateOptionalTime',
135135
'type': 'date'},
136-
# Name for searching.
137-
'name': {'type': 'string', 'analyzer': 'default_icu'},
136+
# Name for searching. This is a list of all the localized
137+
# names for the app. We add "position_offset_gap" to work
138+
# around the fact that ES stores the same list of tokens as
139+
# if this were a single string. The offset gap adds 100
140+
# positions between each name and ensures one string from
141+
# one name and one string from another name won't both
142+
# match with a phrase match query.
143+
'name': {
144+
'type': 'string',
145+
'analyzer': 'default_icu',
146+
'position_offset_gap': 100,
147+
# For exact matches. Referenced as `name.raw`.
148+
'fields': {
149+
'raw': cls.string_not_analyzed(
150+
position_offset_gap=100)
151+
},
152+
},
138153
# Name for sorting.
139154
'name_sort': cls.string_not_analyzed(doc_values=True),
140155
# Name for suggestions.

settings_test.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ def _polite_tmpdir():
5353
DEBUG_PROPAGATE_EXCEPTIONS = False
5454
EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
5555
ES_DEFAULT_NUM_REPLICAS = 0
56-
ES_DEFAULT_NUM_SHARDS = 3
56+
# See the following URL on why we set num_shards to 1 for tests:
57+
# http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/relevance-is-broken.html
58+
ES_DEFAULT_NUM_SHARDS = 1
5759
IARC_MOCK = True
5860
IN_TEST_SUITE = True
5961
INSTALLED_APPS += ('mkt.translations.tests.testapp',)

0 commit comments

Comments
 (0)