Skip to content

Commit f648b4d

Browse files
committed
Merge pull request #4 from mhluongo/master
Fixed a couple errors and added to the README
2 parents 46501ec + 1b30a8c commit f648b4d

File tree

3 files changed

+54
-13
lines changed

3 files changed

+54
-13
lines changed

README.rst

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,25 @@ A basic query can be given by passing in a string into Q's constructor.
2525

2626
The query builder will automatically detect whether a term (no whitespace) or a phrase (multiple terms together seaparated by whitespace) and properly bound them with quotation marks.
2727

28+
All terms and phrases are expected to be unescaped, and will be escaped::
29+
30+
>>> q = Q(r'The *quick* brown (fox)')
31+
32+
>>> str(q)
33+
34+
'"The \\*quick\\* brown \\(fox\\)"'
35+
36+
Range Queries
37+
-------------
38+
2839
Ranges are also easy to put into a query. There are two types of range queries, inclusive range and exclusive range. These are passed into the query builder with keyword arguments.
2940

3041
>>> q = Q(inrange=(1,5))
3142

3243
>>> q = Q(exrange=['egg','hgg'])
3344

34-
Ranges will work with any list-like object.
45+
Ranges will work with any list-like object of length 2.
46+
3547

3648

3749
Chaining Queries
@@ -52,7 +64,7 @@ Nested Queries
5264
Queries can be nested inside of each other to create new queries. This makes it easy to group queries together. Examples below::
5365

5466
>>> q = Q(Q('a') & Q('b')) & ~Q('c')
55-
67+
5668
>>> q = Q(Q(Q('a') | Q(inrange=[1,2])) +Q('c))
5769

5870

@@ -73,4 +85,10 @@ The following examples are invalid queries which will raise an error::
7385
7486
>>> q = Q('bad', Q('range', inrange=[10, 9001]))
7587

88+
89+
Boosting, Wildcards and Fuzzy Queries
90+
--------------------------------------
91+
92+
These queries are not yet supported, but will be soon. Feel free to add support yourself and request a pull!
93+
7694
.. _here: http://lucene.apache.org/java/3_2_0/queryparsersyntax.html

lucenequerybuilder/query.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ def __init__(self, *args, **kwargs):
1414
self._child_has_field = False
1515
if len(args) == 1 and not kwargs:
1616
if Q._check_whitespace(args[0]):
17-
self.should.append('"'+escape(args[0])+'"')
17+
self.should.append('"'+self._escape(args[0])+'"')
1818
else:
19-
self.should.append(escape(args[0]))
19+
self.should.append(self._escape(args[0]))
2020
elif len(args) <= 1 and kwargs:
2121
if kwargs.get('inrange'):
2222
self.inrange = kwargs['inrange']
@@ -33,9 +33,9 @@ def __init__(self, *args, **kwargs):
3333
self.field = args[0]
3434
self._has_field = True
3535
if Q._check_whitespace(args[1]):
36-
self.should.append('"'+_escape(args[1])+'"')
36+
self.should.append('"'+self._escape(args[1])+'"')
3737
else:
38-
self.should.append(_escape(args[1]))
38+
self.should.append(self._escape(args[1]))
3939
if self._check_nested_fields():
4040
raise ValueError('No nested fields allowed.')
4141

@@ -55,10 +55,12 @@ def _escape(cls, s):
5555
if isinstance(s, basestring):
5656
rv = ''
5757
for c in s:
58-
if c in specialchars:
58+
if c in cls.specialchars:
5959
rv += '\\' + c
6060
else:
6161
rv += c
62+
return rv
63+
return s
6264

6365
def _make_and(q1, q2):
6466
q = Q()

lucenequerybuilder/tests.py

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
<<<<<<< Updated upstream:lucenequerybuilder/tests.py
1+
"""
2+
Simple tests for Q. In the future, comparing output to an actual Lucene index
3+
would be a good idea.
4+
"""
5+
26
from lucenequerybuilder import Q
3-
=======
4-
from query import Q
5-
>>>>>>> Stashed changes:querybuilder/tests.py
7+
import re
68

7-
def test_lol():
9+
def test_general():
810
a = 'a'
911
b = 'b'
1012
c = 'c'
@@ -28,4 +30,23 @@ def test_lol():
2830
else:
2931
raise AssertionError("Shouldn't allow nested fields.")
3032

31-
test_lol()
33+
def test_simple_term():
34+
query_string = str(Q('a'))
35+
assert query_string == 'a', query_string
36+
37+
def test_simple_phrase():
38+
query_string = str(Q('abc 123'))
39+
assert query_string == '"abc 123"', query_string
40+
41+
#this test doesn't work, but might be worth rewriting
42+
#
43+
#def test_escaping():
44+
# """ Tests basic character escaping. Doesn't test double char escape, eg &&, ||."""
45+
# special_lucene_chars = r'\+-!(){}[]^"~*?:'
46+
# unescaped_regex = '|'.join([r'(([^\\]|^)%s)' % re.escape(c) for c in special_lucene_chars])
47+
# unescaped_regex = re.compile(unescaped_regex)
48+
# #test the regex
49+
# assert unescaped_regex.match(r'\ [ )') is not None
50+
# query_string = str(Q(':') & Q('\\'))
51+
# #this won't work, dur
52+
# assert not unescaped_regex.match(query_string), query_string

0 commit comments

Comments
 (0)