Skip to content

Commit

Permalink
Multiple types + reverted contains (#127)
Browse files Browse the repository at this point in the history
* Starts/ends/contains keywords

* Multiple contains

* Fix

* comment

* fix

* Fix

* Fix

* Fix

* Typo

* Removed contains

* Fix multiple type

* Fix

* Minor fix
  • Loading branch information
0ssigeno authored Sep 27, 2024
1 parent 008e766 commit 7d3167f
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 64 deletions.
39 changes: 22 additions & 17 deletions atlasq/queryset/index.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fnmatch
from enum import Enum
from logging import getLogger
from typing import Dict, List
from typing import Dict, List, Union

import requests
from atlasq.queryset.exceptions import AtlasIndexError, AtlasIndexFieldError
Expand Down Expand Up @@ -123,22 +123,27 @@ def ensure_index_exists(
self.ensured = False
return self.ensured

def _set_indexed_fields(self, index_result: Dict, base_field: str = ""):
lucene_type = index_result["type"]
if lucene_type in [
AtlasIndexType.DOCUMENT.value,
AtlasIndexType.EMBEDDED_DOCUMENT.value,
]:
if not index_result.get("dynamic", False):
for field, value in index_result.get("fields", {}).items():
field = f"{base_field}.{field}" if base_field else field
self._set_indexed_fields(value, base_field=field)
else:
self._indexed_fields[f"{base_field}.*" if base_field else "*"] = ""
if base_field:
if lucene_type not in AtlasIndexType.values():
logger.warning(f"Lucene type {lucene_type} not configured")
self._indexed_fields[base_field] = lucene_type
def _set_indexed_fields(self, index_result: Union[Dict, List], base_field: str = ""):
if isinstance(index_result, list):
for obj in index_result:
self._set_indexed_fields(obj, base_field=base_field)
else:
lucene_type = index_result["type"]
if lucene_type in [
AtlasIndexType.DOCUMENT.value,
AtlasIndexType.EMBEDDED_DOCUMENT.value,
]:
if not index_result.get("dynamic", False):
for field, value in index_result.get("fields", {}).items():
field = f"{base_field}.{field}" if base_field else field
self._set_indexed_fields(value, base_field=field)
else:
self._indexed_fields[f"{base_field}.*" if base_field else "*"] = ""
if base_field:
if lucene_type not in AtlasIndexType.values():
logger.warning(f"Lucene type {lucene_type} not configured")
else:
self._indexed_fields[base_field] = lucene_type

def _set_indexed_from_mappings(self, index_result: Dict):
mappings = index_result["mappings"]
Expand Down
26 changes: 1 addition & 25 deletions atlasq/queryset/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,7 @@ class AtlasTransform:
equals_type_supported = (bool, ObjectId, int, datetime.datetime)
startswith_keywords = ["startswith", "istartswith"]
endswith_keywords = ["endswith", "iendswith"]
contains_keywords = ["contains", "icontains"]
text_keywords = [
"iwholeword",
"wholeword",
"exact",
"iexact",
"eq",
]
text_keywords = ["iwholeword", "wholeword", "exact", "iexact", "eq", "contains", "icontains"]
all_keywords = ["all"]
regex_keywords = ["regex", "iregex"]
size_keywords = ["size"]
Expand Down Expand Up @@ -319,23 +312,6 @@ def transform(self) -> Tuple[List[Dict], List[Dict], List[Dict]]:
if keyword in self.endswith_keywords:
obj = self._endswith(path, value)
break
if keyword in self.contains_keywords:
# this is because we could have contains__gte=3
try:
comparison_keyword = key_parts[i + 1]
except IndexError:
aggregation = self._contains(path, value, "eq")
else:
aggregation = self._contains(path, value, comparison_keyword)
# we are merging together the contains, because in the 100% of cases we want to match the same object
for j, aggr in enumerate(other_aggregations):
if path in aggr:
# if we have another path__contains__keyword, we merge them
other_aggregations[j] = dict(mergedicts(aggr, aggregation))
break
else:
other_aggregations.append(aggregation)
break
if keyword in self.type_keywords:
if positive == -1:
raise NotImplementedError(f"At the moment you can't have a negative `{keyword}` keyword")
Expand Down
3 changes: 3 additions & 0 deletions tests/queryset/test_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ def test_set_indexed_fields(self):
}
)
self.assertCountEqual(index._indexed_fields, ["*"])
index._indexed_fields.clear()
index._set_indexed_fields([{"type": "string"}, {"type": "number"}], "f")
self.assertCountEqual(index._indexed_fields, ["f"])

def test_ensure_index_exists(self):
index = AtlasIndex("myindex")
Expand Down
22 changes: 0 additions & 22 deletions tests/queryset/test_transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -788,28 +788,6 @@ def test_convert_endswith(self):
self.assertIn("path", res["regex"])
self.assertIn("f", res["regex"]["path"])

def test_contains(self):
q = AtlasQ(f__contains="test")
positive, negative, aggregations = AtlasTransform(q.query, AtlasIndex("test")).transform()
self.assertEqual(positive, [])
self.assertEqual(negative, [])
self.assertEqual(
{"f": {"$elemMatch": {"$eq": "test"}}},
aggregations[0],
json.dumps(aggregations, indent=4),
)

def test_multiple_contains(self):
q = AtlasQ(f__contains__gte="test1", f__contains__lte="test2")
positive, negative, aggregations = AtlasTransform(q.query, AtlasIndex("test")).transform()
self.assertEqual(positive, [])
self.assertEqual(negative, [])
self.assertEqual(
{"f": {"$elemMatch": {"$gte": "test1", "$lte": "test2"}}},
aggregations[0],
json.dumps(aggregations, indent=4),
)

def test__size_operator_not_supported(self):
q = AtlasQ(f=3)
t = AtlasTransform(q.query, AtlasIndex("test"))
Expand Down

0 comments on commit 7d3167f

Please sign in to comment.