[bug 1007319] Switch to match and match_phrase queries.

This commit is contained in:
Ricky Rosario 2014-05-20 10:10:19 -04:00
Родитель e9ae83042a
Коммит a7283e188f
7 изменённых файлов: 53 добавлений и 53 удалений

Просмотреть файл

@ -272,21 +272,21 @@ These are the default weights that apply to all searches:
wiki (aka kb):: wiki (aka kb)::
document_title__text 6 document_title__match 6
document_content__text 1 document_content__match 1
document_keywords__text 8 document_keywords__match 8
document_summary__text 2 document_summary__match 2
questions (aka support forums):: questions (aka support forums)::
question_title__text 4 question_title__match 4
question_content__text 3 question_content__match 3
question_answer_content__text 3 question_answer_content__match 3
forums (aka contributor forums):: forums (aka contributor forums)::
post_title__text 2 post_title__match 2
post_content__text 1 post_content__match 1
Elastic Search is built on top of Lucene so the `Lucene documentation Elastic Search is built on top of Lucene so the `Lucene documentation

Просмотреть файл

@ -15,7 +15,7 @@ class QuestionUpdateTests(ElasticTestCase):
# Create a question--that adds one document to the index. # Create a question--that adds one document to the index.
q = question(title=u'Does this test work?', save=True) q = question(title=u'Does this test work?', save=True)
self.refresh() self.refresh()
query = dict(('%s__text' % field, 'test') query = dict(('%s__match' % field, 'test')
for field in QuestionMappingType.get_query_fields()) for field in QuestionMappingType.get_query_fields())
eq_(search.query(should=True, **query).count(), 1) eq_(search.query(should=True, **query).count(), 1)
@ -24,13 +24,13 @@ class QuestionUpdateTests(ElasticTestCase):
a = answer(content=u'There\'s only one way to find out!', a = answer(content=u'There\'s only one way to find out!',
question=q) question=q)
self.refresh() self.refresh()
query = dict(('%s__text' % field, 'only') query = dict(('%s__match' % field, 'only')
for field in QuestionMappingType.get_query_fields()) for field in QuestionMappingType.get_query_fields())
eq_(search.query(should=True, **query).count(), 0) eq_(search.query(should=True, **query).count(), 0)
a.save() a.save()
self.refresh() self.refresh()
query = dict(('%s__text' % field, 'only') query = dict(('%s__match' % field, 'only')
for field in QuestionMappingType.get_query_fields()) for field in QuestionMappingType.get_query_fields())
eq_(search.query(should=True, **query).count(), 1) eq_(search.query(should=True, **query).count(), 1)
@ -44,11 +44,11 @@ class QuestionUpdateTests(ElasticTestCase):
q = question(title=u'Does this work?', save=True) q = question(title=u'Does this work?', save=True)
self.refresh() self.refresh()
eq_(search.query(question_title__text='work').count(), 1) eq_(search.query(question_title__match='work').count(), 1)
q.delete() q.delete()
self.refresh() self.refresh()
eq_(search.query(question_title__text='work').count(), 0) eq_(search.query(question_title__match='work').count(), 0)
def test_question_one_answer_deleted(self): def test_question_one_answer_deleted(self):
search = QuestionMappingType.search() search = QuestionMappingType.search()
@ -59,19 +59,19 @@ class QuestionUpdateTests(ElasticTestCase):
# Question and its answers are a single document--so the # Question and its answers are a single document--so the
# index count should be only 1. # index count should be only 1.
eq_(search.query(question_title__text='pink').count(), 1) eq_(search.query(question_title__match='pink').count(), 1)
# After deleting the answer, the question document should # After deleting the answer, the question document should
# remain. # remain.
a.delete() a.delete()
self.refresh() self.refresh()
eq_(search.query(question_title__text='pink').count(), 1) eq_(search.query(question_title__match='pink').count(), 1)
# Delete the question and it should be removed from the # Delete the question and it should be removed from the
# index. # index.
q.delete() q.delete()
self.refresh() self.refresh()
eq_(search.query(question_title__text='pink').count(), 0) eq_(search.query(question_title__match='pink').count(), 0)
def test_question_questionvote(self): def test_question_questionvote(self):
search = QuestionMappingType.search() search = QuestionMappingType.search()
@ -154,11 +154,11 @@ class QuestionUpdateTests(ElasticTestCase):
q = question(title=u'Does this work?', save=True) q = question(title=u'Does this work?', save=True)
self.refresh() self.refresh()
eq_(search.query(question_title__text='work').count(), 1) eq_(search.query(question_title__match='work').count(), 1)
q.creator.delete() q.creator.delete()
self.refresh() self.refresh()
eq_(search.query(question_title__text='work').count(), 0) eq_(search.query(question_title__match='work').count(), 0)
def test_question_is_reindexed_on_username_change(self): def test_question_is_reindexed_on_username_change(self):
search = QuestionMappingType.search() search = QuestionMappingType.search()
@ -168,9 +168,9 @@ class QuestionUpdateTests(ElasticTestCase):
q = question(creator=u, title=u'Hello', save=True) q = question(creator=u, title=u'Hello', save=True)
a = answer(creator=u, content=u'I love you', save=True) a = answer(creator=u, content=u'I love you', save=True)
self.refresh() self.refresh()
eq_(search.query(question_title__text='hello')[0]['question_creator'], eq_(search.query(question_title__match='hello')[0]['question_creator'],
u'dexter') u'dexter')
query = search.query(question_answer_content__text='love') query = search.query(question_answer_content__match='love')
eq_(query[0]['question_answer_creator'], eq_(query[0]['question_answer_creator'],
[u'dexter']) [u'dexter'])
@ -178,9 +178,9 @@ class QuestionUpdateTests(ElasticTestCase):
u.username = 'walter' u.username = 'walter'
u.save() u.save()
self.refresh() self.refresh()
eq_(search.query(question_title__text='hello')[0]['question_creator'], eq_(search.query(question_title__match='hello')[0]['question_creator'],
u'walter') u'walter')
query = search.query(question_answer_content__text='love') query = search.query(question_answer_content__match='love')
eq_(query[0]['question_answer_creator'], [u'walter']) eq_(query[0]['question_answer_creator'], [u'walter'])
@ -196,8 +196,8 @@ class QuestionSearchTests(ElasticTestCase):
helpful=True).save() helpful=True).save()
self.refresh() self.refresh()
result = QuestionMappingType.search().query( result = QuestionMappingType.search().query(
question_title__text='LOLRUS', question_title__match='LOLRUS',
question_content__text='LOLRUS') question_content__match='LOLRUS')
assert result.count() > 0 assert result.count() > 0

Просмотреть файл

@ -1593,9 +1593,9 @@ def _search_suggestions(request, text, locale, product_slugs):
results = [] results = []
try: try:
# Search for relevant KB documents. # Search for relevant KB documents.
query = dict(('%s__text' % field, text) query = dict(('%s__match' % field, text)
for field in DocumentMappingType.get_query_fields()) for field in DocumentMappingType.get_query_fields())
query.update(dict(('%s__text_phrase' % field, text) query.update(dict(('%s__match_phrase' % field, text)
for field in DocumentMappingType.get_query_fields())) for field in DocumentMappingType.get_query_fields()))
query = es_query_with_analyzer(query, locale) query = es_query_with_analyzer(query, locale)
filter = F() filter = F()
@ -1624,9 +1624,9 @@ def _search_suggestions(request, text, locale, product_slugs):
pass pass
# Search for relevant questions. # Search for relevant questions.
query = dict(('%s__text' % field, text) query = dict(('%s__match' % field, text)
for field in QuestionMappingType.get_query_fields()) for field in QuestionMappingType.get_query_fields())
query.update(dict(('%s__text_phrase' % field, text) query.update(dict(('%s__match_phrase' % field, text)
for field in QuestionMappingType.get_query_fields())) for field in QuestionMappingType.get_query_fields()))
max_age = int(time.time()) - settings.SEARCH_DEFAULT_MAX_QUESTION_AGE max_age = int(time.time()) - settings.SEARCH_DEFAULT_MAX_QUESTION_AGE

Просмотреть файл

@ -66,8 +66,8 @@ class AnalyzerMixin(object):
:arg key: is the field being searched :arg key: is the field being searched
:arg val: Is a two-tupe of the text to query for and the name of :arg val: Is a two-tupe of the text to query for and the name of
the analyzer to use. the analyzer to use.
:arg action: is the type of query being performed, like text or :arg action: is the type of query being performed, like match or
text_phrase match_phrase
""" """
query, analyzer = val query, analyzer = val
clause = { clause = {
@ -85,13 +85,13 @@ class AnalyzerMixin(object):
return clause return clause
def process_query_text_phrase_analyzer(self, key, val, action): def process_query_match_phrase_analyzer(self, key, val, action):
"""A text phrase query that includes an analyzer.""" """A match phrase query that includes an analyzer."""
return self._with_analyzer(key, val, 'text_phrase') return self._with_analyzer(key, val, 'match_phrase')
def process_query_text_analyzer(self, key, val, action): def process_query_match_analyzer(self, key, val, action):
"""A text query that includes an analyzer.""" """A match query that includes an analyzer."""
return self._with_analyzer(key, val, 'text') return self._with_analyzer(key, val, 'match')
class Sphilastic(S, AnalyzerMixin): class Sphilastic(S, AnalyzerMixin):

Просмотреть файл

@ -1123,16 +1123,16 @@ class TestAnalyzers(ElasticTestCase):
def test_query_analyzer_upgrader(self): def test_query_analyzer_upgrader(self):
analyzer = 'snowball-english-synonyms' analyzer = 'snowball-english-synonyms'
before = { before = {
'document_title__text': 'foo', 'document_title__match': 'foo',
'document_locale__text': 'bar', 'document_locale__match': 'bar',
'document_title__text_phrase': 'baz', 'document_title__match_phrase': 'baz',
'document_locale__text_phrase': 'qux' 'document_locale__match_phrase': 'qux'
} }
expected = { expected = {
'document_title__text_analyzer': ('foo', analyzer), 'document_title__match_analyzer': ('foo', analyzer),
'document_locale__text': 'bar', 'document_locale__match': 'bar',
'document_title__text_phrase_analyzer': ('baz', analyzer), 'document_title__match_phrase_analyzer': ('baz', analyzer),
'document_locale__text_phrase': 'qux', 'document_locale__match_phrase': 'qux',
} }
actual = es_utils.es_query_with_analyzer(before, 'en-US') actual = es_utils.es_query_with_analyzer(before, 'en-US')
eq_(actual, expected) eq_(actual, expected)

Просмотреть файл

@ -323,8 +323,8 @@ def search(request, template=None):
# Text phrases in document titles and content get an extra # Text phrases in document titles and content get an extra
# boost. # boost.
document_title__text_phrase=10.0, document_title__match_phrase=10.0,
document_content__text_phrase=8.0) document_content__match_phrase=8.0)
# Apply sortby for advanced search of questions # Apply sortby for advanced search of questions
if cleaned['w'] == constants.WHERE_SUPPORT: if cleaned['w'] == constants.WHERE_SUPPORT:
@ -358,10 +358,10 @@ def search(request, template=None):
] ]
) )
query = {} query = {}
# Create text and text_phrase queries for every field # Create match and match_phrase queries for every field
# we want to search. # we want to search.
for field in query_fields: for field in query_fields:
for query_type in ['text', 'text_phrase']: for query_type in ['match', 'match_phrase']:
query['%s__%s' % (field, query_type)] = cleaned_q query['%s__%s' % (field, query_type)] = cleaned_q
# Transform the query to use locale aware analyzers. # Transform the query to use locale aware analyzers.
@ -530,7 +530,7 @@ def suggestions(request):
site = Site.objects.get_current() site = Site.objects.get_current()
locale = locale_or_default(request.LANGUAGE_CODE) locale = locale_or_default(request.LANGUAGE_CODE)
try: try:
query = dict(('%s__text' % field, term) query = dict(('%s__match' % field, term)
for field in DocumentMappingType.get_query_fields()) for field in DocumentMappingType.get_query_fields())
# Upgrade the query to an analyzer-aware one. # Upgrade the query to an analyzer-aware one.
query = es_utils.es_query_with_analyzer(query, locale) query = es_utils.es_query_with_analyzer(query, locale)
@ -541,7 +541,7 @@ def suggestions(request):
.values_dict('document_title', 'url') .values_dict('document_title', 'url')
.query(or_=query)[:5]) .query(or_=query)[:5])
query = dict(('%s__text' % field, term) query = dict(('%s__match' % field, term)
for field in QuestionMappingType.get_query_fields()) for field in QuestionMappingType.get_query_fields())
question_s = (QuestionMappingType.search() question_s = (QuestionMappingType.search()
.filter(question_has_helpful=True) .filter(question_has_helpful=True)

Просмотреть файл

@ -114,7 +114,7 @@ class DocumentUpdateTests(ElasticTestCase):
revision(document=doc, is_approved=True, save=True) revision(document=doc, is_approved=True, save=True)
self.refresh() self.refresh()
eq_(DocumentMappingType.search().query( eq_(DocumentMappingType.search().query(
document_title__text='wool').count(), 1) document_title__match='wool').count(), 1)
# Now create a revision that is a redirect and make sure the # Now create a revision that is a redirect and make sure the
# document is removed from the index. # document is removed from the index.
@ -122,7 +122,7 @@ class DocumentUpdateTests(ElasticTestCase):
save=True) save=True)
self.refresh() self.refresh()
eq_(DocumentMappingType.search().query( eq_(DocumentMappingType.search().query(
document_title__text='wool').count(), 0) document_title__match='wool').count(), 0)
def test_wiki_keywords(self): def test_wiki_keywords(self):
"""Make sure updating keywords updates the index.""" """Make sure updating keywords updates the index."""