Skip to content

Commit f0eacb9

Browse files
committed
Better Solr AltParser quoting (closes django-haystack#730)
Previously the Solr AltParser implementation embedded the search term as an attribte inside the {!…} construct, which required it to be doubly escaped. This change contributed by @ivirabyan moves the value outside the query, requiring only our normal quoting: q=(_query_:"{!edismax}Assassin's Creed") instead of: q=(_query_:"{!edismax v='Assassin's Creed'}") Thanks @ivirabyan for the patch!
1 parent 1e087f6 commit f0eacb9

File tree

4 files changed

+30
-6
lines changed

4 files changed

+30
-6
lines changed

haystack/backends/solr_backend.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ def build_query_fragment(self, field, filter_type, value):
592592

593593
def build_alt_parser_query(self, parser_name, query_string='', **kwargs):
594594
if query_string:
595-
kwargs['v'] = Clean(query_string).prepare(self)
595+
query_string = Clean(query_string).prepare(self)
596596

597597
kwarg_bits = []
598598

@@ -602,7 +602,7 @@ def build_alt_parser_query(self, parser_name, query_string='', **kwargs):
602602
else:
603603
kwarg_bits.append(u"%s=%s" % (key, kwargs[key]))
604604

605-
return u'_query_:"{!%s %s}"' % (parser_name, Clean(' '.join(kwarg_bits)))
605+
return u'_query_:"{!%s %s}%s"' % (parser_name, Clean(' '.join(kwarg_bits)), query_string)
606606

607607
def build_params(self, spelling_query=None, **kwargs):
608608
search_kwargs = {

tests/solr_tests/tests/inputs.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,8 @@ def test_altparser_init(self):
7878
def test_altparser_prepare(self):
7979
altparser = inputs.AltParser('dismax', 'douglas adams', qf='author', mm=1)
8080
self.assertEqual(altparser.prepare(self.query_obj),
81-
u"""_query_:"{!dismax mm=1 qf=author v='douglas adams'}\"""")
81+
u"""_query_:"{!dismax mm=1 qf=author}douglas adams\"""")
82+
83+
altparser = inputs.AltParser('dismax', 'Don\'t panic', qf='text author', mm=1)
84+
self.assertEqual(altparser.prepare(self.query_obj),
85+
u"""_query_:"{!dismax mm=1 qf='text author'}Don't panic\"""")

tests/solr_tests/tests/solr_backend.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,16 @@ def get_model(self):
162162
return ASixthMockModel
163163

164164

165+
class SolrQuotingMockSearchIndex(indexes.SearchIndex, indexes.Indexable):
166+
text = indexes.CharField(document=True, use_template=True)
167+
168+
def get_model(self):
169+
return MockModel
170+
171+
def prepare_text(self, obj):
172+
return u"""Don't panic but %s has been iñtërnâtiônàlizéð""" % obj.author
173+
174+
165175
class SolrSearchBackendTestCase(TestCase):
166176
def setUp(self):
167177
super(SolrSearchBackendTestCase, self).setUp()
@@ -362,7 +372,7 @@ def test_search(self):
362372
def test_altparser_query(self):
363373
self.sb.update(self.smmi, self.sample_objs)
364374

365-
results = self.sb.search(AltParser('dismax', 'daniel1', qf='name', mm=1).prepare(self.sq))
375+
results = self.sb.search(AltParser('dismax', "daniel1", qf='name', mm=1).prepare(self.sq))
366376
self.assertEqual(results['hits'], 1)
367377

368378
# This should produce exactly the same result since all we have are mockmodel instances but we simply
@@ -387,6 +397,16 @@ def test_altparser_query(self):
387397
self.assertEqual(len(results), 1)
388398
self.assertEqual(results[0].id, 'core.mockmodel.1')
389399

400+
def test_altparser_quoting(self):
401+
test_objs = [
402+
MockModel(id=1, author="Foo d'Bar", pub_date=datetime.date.today()),
403+
MockModel(id=2, author="Baaz Quuz", pub_date=datetime.date.today()),
404+
]
405+
self.sb.update(SolrQuotingMockSearchIndex(), test_objs)
406+
407+
results = self.sb.search(AltParser('dismax', "+don't +quuz", qf='text').prepare(self.sq))
408+
self.assertEqual(results['hits'], 1)
409+
390410
def test_more_like_this(self):
391411
self.sb.update(self.smmi, self.sample_objs)
392412
self.assertEqual(self.raw_solr.search('*:*').hits, 3)

tests/solr_tests/tests/solr_query.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,14 @@ def test_build_query_multiple_filter_types(self):
7575
self.assertEqual(self.sq.build_query(), u'((why) AND pub_date:([* TO "2009-02-10 01:59:00"]) AND author:({"daniel" TO *}) AND created:({* TO "2009-02-12 12:13:00"}) AND title:(["B" TO *]) AND id:("1" OR "2" OR "3") AND rating:(["3" TO "5"]))')
7676

7777
def test_build_complex_altparser_query(self):
78-
self.sq.add_filter(SQ(content=AltParser('dismax', 'why', qf='text')))
78+
self.sq.add_filter(SQ(content=AltParser('dismax', "Don't panic", qf='text')))
7979
self.sq.add_filter(SQ(pub_date__lte=Exact('2009-02-10 01:59:00')))
8080
self.sq.add_filter(SQ(author__gt='daniel'))
8181
self.sq.add_filter(SQ(created__lt=Exact('2009-02-12 12:13:00')))
8282
self.sq.add_filter(SQ(title__gte='B'))
8383
self.sq.add_filter(SQ(id__in=[1, 2, 3]))
8484
self.sq.add_filter(SQ(rating__range=[3, 5]))
85-
self.assertEqual(self.sq.build_query(), u'((_query_:"{!dismax qf=text v=why}") AND pub_date:([* TO "2009-02-10 01:59:00"]) AND author:({"daniel" TO *}) AND created:({* TO "2009-02-12 12:13:00"}) AND title:(["B" TO *]) AND id:("1" OR "2" OR "3") AND rating:(["3" TO "5"]))')
85+
self.assertEqual(self.sq.build_query(), u'((_query_:"{!dismax qf=text}Don\'t panic") AND pub_date:([* TO "2009-02-10 01:59:00"]) AND author:({"daniel" TO *}) AND created:({* TO "2009-02-12 12:13:00"}) AND title:(["B" TO *]) AND id:("1" OR "2" OR "3") AND rating:(["3" TO "5"]))')
8686

8787
def test_build_query_multiple_filter_types_with_datetimes(self):
8888
self.sq.add_filter(SQ(content='why'))

0 commit comments

Comments
 (0)