Skip to content

Commit 20cee68

Browse files
committed
new: highlight() accepts custom values on Solr and ES
This allows the default values to be overriden and arbitrary backend-specific parameters may be provided to Solr or ElasticSearch. Thanks to @tymofij for the patch Closes django-haystack#1334
1 parent 96df8f4 commit 20cee68

File tree

5 files changed

+33
-7
lines changed

5 files changed

+33
-7
lines changed

haystack/backends/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -854,9 +854,9 @@ def add_stats_query(self,stats_field,stats_facets):
854854
"""Adds stats and stats_facets queries for the Solr backend."""
855855
self.stats[stats_field] = stats_facets
856856

857-
def add_highlight(self):
857+
def add_highlight(self, **kwargs):
858858
"""Adds highlighting to the search results."""
859-
self.highlight = True
859+
self.highlight = kwargs or True
860860

861861
def add_within(self, field, point_1, point_2):
862862
"""Adds bounding box parameters to search query."""

haystack/backends/elasticsearch_backend.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,13 +322,19 @@ def build_search_kwargs(self, query_string, sort_by=None, start_offset=0, end_of
322322
# if end_offset is not None:
323323
# kwargs['size'] = end_offset - start_offset
324324

325-
if highlight is True:
325+
if highlight:
326+
# `highlight` can either be True or a dictionary containing custom parameters
327+
# which will be passed to the backend and may override our default settings:
328+
326329
kwargs['highlight'] = {
327330
'fields': {
328331
content_field: {'store': 'yes'},
329332
}
330333
}
331334

335+
if isinstance(highlight, dict):
336+
kwargs['highlight'].update(highlight)
337+
332338
if self.include_spelling:
333339
kwargs['suggest'] = {
334340
'suggest': {

haystack/backends/solr_backend.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,16 @@ def build_search_kwargs(self, query_string, sort_by=None, start_offset=0, end_of
180180
if end_offset is not None:
181181
kwargs['rows'] = end_offset - start_offset
182182

183-
if highlight is True:
183+
if highlight:
184+
# `highlight` can either be True or a dictionary containing custom parameters
185+
# which will be passed to the backend and may override our default settings:
186+
184187
kwargs['hl'] = 'true'
185188
kwargs['hl.fragsize'] = '200'
186189

190+
if isinstance(highlight, dict):
191+
kwargs.update(highlight)
192+
187193
if self.include_spelling is True:
188194
kwargs['spellcheck'] = 'true'
189195
kwargs['spellcheck.collate'] = 'true'

haystack/query.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from haystack import connection_router, connections
1111
from haystack.backends import SQ
12-
from haystack.constants import DEFAULT_OPERATOR, ITERATOR_LOAD_PER_QUERY, REPR_OUTPUT_SIZE
12+
from haystack.constants import DEFAULT_OPERATOR, ITERATOR_LOAD_PER_QUERY
1313
from haystack.exceptions import NotHandled
1414
from haystack.inputs import AutoQuery, Raw
1515
from haystack.utils import log as logging
@@ -313,10 +313,10 @@ def order_by(self, *args):
313313

314314
return clone
315315

316-
def highlight(self):
316+
def highlight(self, **kwargs):
317317
"""Adds highlighting to the results."""
318318
clone = self._clone()
319-
clone.query.add_highlight()
319+
clone.query.add_highlight(**kwargs)
320320
return clone
321321

322322
def models(self, *models):

test_haystack/elasticsearch_tests/test_elasticsearch_backend.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,9 @@ def test_search(self):
424424
self.assertEqual(self.sb.search('Index', highlight=True)['hits'], 3)
425425
self.assertEqual(sorted([result.highlighted[0] for result in self.sb.search('Index', highlight=True)['results']]),
426426
[u'<em>Indexed</em>!\n1', u'<em>Indexed</em>!\n2', u'<em>Indexed</em>!\n3'])
427+
self.assertEqual(sorted([result.highlighted[0] for result in self.sb.search('Index', highlight={'pre_tags': ['<start>'],'post_tags': ['</end>']})['results']]),
428+
[u'<start>Indexed</end>!\n1', u'<start>Indexed</end>!\n2', u'<start>Indexed</end>!\n3'])
429+
427430

428431
self.assertEqual(self.sb.search('Indx')['hits'], 0)
429432
self.assertEqual(self.sb.search('indaxed')['spelling_suggestion'], 'indexed')
@@ -764,6 +767,17 @@ def test_count(self):
764767
# Should only execute one query to count the length of the result set.
765768
self.assertEqual(len(connections['elasticsearch'].queries), 1)
766769

770+
def test_highlight(self):
771+
reset_search_queries()
772+
results = self.sqs.filter(content='index').highlight()
773+
self.assertEqual(results[0].highlighted, [u'<em>Indexed</em>!\n1'])
774+
775+
def test_highlight_options(self):
776+
reset_search_queries()
777+
results = self.sqs.filter(content='index')
778+
results = results.highlight(pre_tags=['<i>'], post_tags=['</i>'])
779+
self.assertEqual(results[0].highlighted, [u'<i>Indexed</i>!\n1'])
780+
767781
def test_manual_iter(self):
768782
results = self.sqs.all()
769783

0 commit comments

Comments
 (0)