Skip to content

Commit

Permalink
Regex transformation
Browse files Browse the repository at this point in the history
Embedded document text search
Bump to 0.3.0
  • Loading branch information
0ssigeno committed Aug 31, 2022
1 parent 3e102f7 commit 0976032
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 19 deletions.
37 changes: 33 additions & 4 deletions atlasq/queryset/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class AtlasTransform:
"iwholeword",
"wholeword",
]
regex_keywords = ["regex", "iregex"]
size_keywords = ["size"]
not_converted = [
"all",
Expand All @@ -55,14 +56,33 @@ class AtlasTransform:
"contains",
"icontains",
"mod",
"regex",
"iregex",
"match",
]

def __init__(self, atlas_query):
self.atlas_query = atlas_query

def _regex(self, path: str, value: str):
return {"regex": {"query": value, "path": path}}

def _embedded_document(self, path: List[str], operator: Dict):
# recursive
if len(path) > 2:
new_path = path[1:]
new_path[0] = f"{path[0]}.{new_path[0]}"

return {
"embeddedDocument": {
"path": path[0],
"operator": self._embedded_document(new_path, operator),
}
}
# real exit case
if len(path) > 1:
return {"embeddedDocument": {"path": path[0], "operator": operator}}
# we do nothing in case it was not an embedded document
return operator

def _exists(self, path: str, empty: bool) -> Dict:
# false True == true == eq
# true False == true == eq
Expand Down Expand Up @@ -185,21 +205,30 @@ def transform(
if keyword in self.text_keywords:
obj = self._text(path, value)
break
if keyword in self.regex_keywords:
obj = self._regex(path, value)
break
else:
if not path:
path = ".".join(key_parts)
self._ensure_keyword_is_indexed(atlas_index, path)
if isinstance(value, bool):
obj = self._equals(path, value)

else:
obj = self._text(path, value)

if obj:
# we are wrapping the result to an embedded document
obj = self._embedded_document(path.split("."), obj)
logger.debug(obj)

if to_go == 1:
affirmative.append(obj)
else:
negative.append(obj)

if other_aggregations:
logger.warning(
"CARE! You are generating a query that uses other aggregations other than text search!"
f" Aggregations generated are {other_aggregations}"
)
return affirmative, negative, other_aggregations
62 changes: 48 additions & 14 deletions tests/queryset/test_transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ def test__ensure_keyword(self):
with self.assertRaises(AtlasIndexFieldError):
AtlasTransform(q.query).transform(index)

def test__regex(self):
q = AtlasQ(f__regex=".*")
t = AtlasTransform(q.query)
res = t._regex("f", ".*")
self.assertIn("regex", res)
self.assertIn("query", res["regex"])
self.assertIn(".*", res["regex"]["query"])
self.assertIn("path", res["regex"])
self.assertIn("f", res["regex"]["path"])

def test__queryset_value(self):
class MyDoc(Document):
field = fields.StringField()
Expand Down Expand Up @@ -371,49 +381,73 @@ def test_atlas_q_not_whole_word(self):
)

def test_atlas_q_field_start_with_keyword(self):
q1 = AtlasQ(key__internal__in=["value"])
q1 = AtlasQ(key__in=["value"])
positive, negative, aggregations = AtlasTransform(q1.query).transform(
AtlasIndex("test")
)
self.assertEqual([], aggregations)
self.assertEqual([], negative)
self.assertEqual(
[
{"text": {"path": "key.internal", "query": ["value"]}},
{"text": {"path": "key", "query": ["value"]}},
],
positive,
json.dumps(positive, indent=4),
)

def test_atlas_q_ne_embedded_document(self):
q1 = AtlasQ(key__internal__key__ne="value")
positive, negative, aggregations = AtlasTransform(q1.query).transform(
q = AtlasQ(f__g__h__ne="test")
positive, negative, aggregations = AtlasTransform(q.query).transform(
AtlasIndex("test")
)
self.assertEqual([], aggregations)
self.assertEqual([], positive)
self.assertEqual(
negative,
[
{"text": {"path": "key.internal.key", "query": "value"}},
{
"embeddedDocument": {
"path": "f",
"operator": {
"embeddedDocument": {
"path": "f.g",
"operator": {
"text": {"query": "test", "path": "f.g.h"}
},
}
},
}
}
],
negative,
json.dumps(negative, indent=4),
)
self.assertEqual(positive, [])
self.assertEqual(aggregations, [])

def test_atlas_q_embedded_document(self):
q1 = AtlasQ(key__internal__key="value")
positive, negative, aggregations = AtlasTransform(q1.query).transform(
q = AtlasQ(f__g__h="test")
positive, negative, aggregations = AtlasTransform(q.query).transform(
AtlasIndex("test")
)
self.assertEqual([], aggregations)
self.assertEqual([], negative)
self.assertEqual(
positive,
[
{"text": {"path": "key.internal.key", "query": "value"}},
{
"embeddedDocument": {
"path": "f",
"operator": {
"embeddedDocument": {
"path": "f.g",
"operator": {
"text": {"query": "test", "path": "f.g.h"}
},
}
},
}
}
],
positive,
json.dumps(positive, indent=4),
)
self.assertEqual(negative, [])
self.assertEqual(aggregations, [])

def test_atlas_q_nin(self):
q1 = AtlasQ(key__nin=["value", "value2"])
Expand Down
2 changes: 1 addition & 1 deletion version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION = "0.2.7"
VERSION = "0.3.0"

0 comments on commit 0976032

Please sign in to comment.