Mongo
MongoTransformer (Transformer)
¶
Support for grammar v0.10.1
__init__(self, mapper=None)
special
¶
Initialise the object, optionally loading in a resource mapper for use when post-processing.
Source code in optimade/filtertransformers/mongo.py
def __init__(self, mapper: BaseResourceMapper = None):
""" Initialise the object, optionally loading in a
resource mapper for use when post-processing.
"""
self.mapper = mapper
super().__init__()
non_string_value(self, value)
¶
non_string_value: number | property
Source code in optimade/filtertransformers/mongo.py
@v_args(inline=True)
def non_string_value(self, value):
""" non_string_value: number | property """
# Note: Do nothing!
return value
not_implemented_string(self, value)
¶
not_implemented_string: value
Raise NotImplementedError. For further information, see Materials-Consortia/OPTIMADE issue 157: https://github.com/Materials-Consortia/OPTIMADE/issues/157
Source code in optimade/filtertransformers/mongo.py
@v_args(inline=True)
def not_implemented_string(self, value):
""" not_implemented_string: value
Raise NotImplementedError.
For further information, see Materials-Consortia/OPTIMADE issue 157:
https://github.com/Materials-Consortia/OPTIMADE/issues/157
"""
raise NotImplementedError("Comparing strings is not yet implemented.")
postprocess(self, query)
¶
Used to post-process the final parsed query.
Source code in optimade/filtertransformers/mongo.py
def postprocess(self, query):
""" Used to post-process the final parsed query. """
if self.mapper:
# important to apply length alias before normal aliases
query = self._apply_length_aliases(query)
query = self._apply_aliases(query)
query = self._apply_relationship_filtering(query)
query = self._apply_length_operators(query)
query = self._apply_unknown_or_null_filter(query)
return query
transform(self, tree)
¶
Transform the given tree, and return the final result
Source code in optimade/filtertransformers/mongo.py
def transform(self, tree):
return self.postprocess(super().transform(tree))
recursive_postprocessing(filter_, condition, replacement)
¶
Recursively descend into the query, checking each dictionary (contained in a list, or as an entry in another dictionary) for the condition passed. If the condition is true, apply the replacement to the dictionary.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
filter_ |
list/dict |
the filter_ to process. |
required |
condition |
callable |
a function that returns True if the
replacement function should be applied. It should take
as arguments the property and expression from the filter_,
as would be returned by iterating over |
required |
replacement |
callable |
a function that returns the processed dictionary. It should take as arguments the dictionary to modify, the property and the expression (as described above). |
required |
Examples:
For the simple case of replacing one field name with another, the following functions could be used:
def condition(prop, expr):
return prop == "field_name_old"
def replacement(d, prop, expr):
d["field_name_old"] = d.pop(prop)
filter_ = recursive_postprocessing(
filter_, condition, replacement
)
Source code in optimade/filtertransformers/mongo.py
def recursive_postprocessing(filter_, condition, replacement):
""" Recursively descend into the query, checking each dictionary
(contained in a list, or as an entry in another dictionary) for
the condition passed. If the condition is true, apply the
replacement to the dictionary.
Parameters:
filter_ (list/dict): the filter_ to process.
condition (callable): a function that returns True if the
replacement function should be applied. It should take
as arguments the property and expression from the filter_,
as would be returned by iterating over `filter_.items()`.
replacement (callable): a function that returns the processed
dictionary. It should take as arguments the dictionary
to modify, the property and the expression (as described
above).
Example:
For the simple case of replacing one field name with
another, the following functions could be used:
```python
def condition(prop, expr):
return prop == "field_name_old"
def replacement(d, prop, expr):
d["field_name_old"] = d.pop(prop)
filter_ = recursive_postprocessing(
filter_, condition, replacement
)
```
"""
if isinstance(filter_, list):
result = [recursive_postprocessing(q, condition, replacement) for q in filter_]
return result
if isinstance(filter_, dict):
# this could potentially lead to memory leaks if the filter_ is *heavily* nested
_cached_filter = copy.deepcopy(filter_)
for prop, expr in filter_.items():
if condition(prop, expr):
_cached_filter = replacement(_cached_filter, prop, expr)
elif isinstance(expr, list):
_cached_filter[prop] = [
recursive_postprocessing(q, condition, replacement) for q in expr
]
return _cached_filter
return filter_