Merge pull request #2568 from idoshr/regex_query
Regex and whole word text search query
This commit is contained in:
commit
8c3e2b340b
@ -86,6 +86,10 @@ expressions:
|
||||
* ``istartswith`` -- string field starts with value (case insensitive)
|
||||
* ``endswith`` -- string field ends with value
|
||||
* ``iendswith`` -- string field ends with value (case insensitive)
|
||||
* ``wholeword`` -- string field contains whole word
|
||||
* ``iwholeword`` -- string field contains whole word (case insensitive)
|
||||
* ``regex`` -- string field match by regex
|
||||
* ``iregex`` -- string field match by regex (case insensitive)
|
||||
* ``match`` -- performs an $elemMatch so you can match an entire document within an array
|
||||
|
||||
|
||||
|
@ -157,10 +157,17 @@ class StringField(BaseField):
|
||||
regex = r"%s$"
|
||||
elif op == "exact":
|
||||
regex = r"^%s$"
|
||||
elif op == "wholeword":
|
||||
regex = r"\b%s\b"
|
||||
elif op == "regex":
|
||||
regex = value
|
||||
|
||||
# escape unsafe characters which could lead to a re.error
|
||||
value = re.escape(value)
|
||||
value = re.compile(regex % value, flags)
|
||||
if op == "regex":
|
||||
value = re.compile(regex, flags)
|
||||
else:
|
||||
value = re.escape(value)
|
||||
value = re.compile(regex % value, flags)
|
||||
return super().prepare_query_value(op, value)
|
||||
|
||||
|
||||
@ -1086,16 +1093,7 @@ class DictField(ComplexBaseField):
|
||||
return DictField(db_field=member_name)
|
||||
|
||||
def prepare_query_value(self, op, value):
|
||||
match_operators = [
|
||||
"contains",
|
||||
"icontains",
|
||||
"startswith",
|
||||
"istartswith",
|
||||
"endswith",
|
||||
"iendswith",
|
||||
"exact",
|
||||
"iexact",
|
||||
]
|
||||
match_operators = [*STRING_OPERATORS]
|
||||
|
||||
if op in match_operators and isinstance(value, str):
|
||||
return StringField().prepare_query_value(op, value)
|
||||
|
@ -51,6 +51,10 @@ STRING_OPERATORS = (
|
||||
"iendswith",
|
||||
"exact",
|
||||
"iexact",
|
||||
"regex",
|
||||
"iregex",
|
||||
"wholeword",
|
||||
"iwholeword",
|
||||
)
|
||||
CUSTOM_OPERATORS = ("match",)
|
||||
MATCH_OPERATORS = (
|
||||
|
@ -1255,6 +1255,34 @@ class TestQueryset(unittest.TestCase):
|
||||
obj = self.Person.objects(name__iexact="gUIDO VAN rOSSU").first()
|
||||
assert obj is None
|
||||
|
||||
# Test wholeword
|
||||
obj = self.Person.objects(name__wholeword="Guido").first()
|
||||
assert obj == person
|
||||
obj = self.Person.objects(name__wholeword="rossum").first()
|
||||
assert obj is None
|
||||
obj = self.Person.objects(name__wholeword="Rossu").first()
|
||||
assert obj is None
|
||||
|
||||
# Test iwholeword
|
||||
obj = self.Person.objects(name__iwholeword="rOSSUM").first()
|
||||
assert obj == person
|
||||
obj = self.Person.objects(name__iwholeword="rOSSU").first()
|
||||
assert obj is None
|
||||
|
||||
# Test regex
|
||||
obj = self.Person.objects(name__regex="^[Guido].*[Rossum]$").first()
|
||||
assert obj == person
|
||||
obj = self.Person.objects(name__regex="^[guido].*[rossum]$").first()
|
||||
assert obj is None
|
||||
obj = self.Person.objects(name__regex="^[uido].*[Rossum]$").first()
|
||||
assert obj is None
|
||||
|
||||
# Test iregex
|
||||
obj = self.Person.objects(name__iregex="^[guido].*[rossum]$").first()
|
||||
assert obj == person
|
||||
obj = self.Person.objects(name__iregex="^[Uido].*[Rossum]$").first()
|
||||
assert obj is None
|
||||
|
||||
# Test unsafe expressions
|
||||
person = self.Person(name="Guido van Rossum [.'Geek']")
|
||||
person.save()
|
||||
@ -1339,7 +1367,14 @@ class TestQueryset(unittest.TestCase):
|
||||
person.save()
|
||||
|
||||
people = self.Person.objects
|
||||
people = people.filter(name__startswith="Gui").filter(name__not__endswith="tum")
|
||||
people = (
|
||||
people.filter(name__startswith="Gui")
|
||||
.filter(name__not__endswith="tum")
|
||||
.filter(name__icontains="VAN")
|
||||
.filter(name__regex="^Guido")
|
||||
.filter(name__wholeword="Guido")
|
||||
.filter(name__wholeword="van")
|
||||
)
|
||||
assert people.count() == 1
|
||||
|
||||
def assertSequence(self, qs, expected):
|
||||
|
Loading…
x
Reference in New Issue
Block a user