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_