[docs]classElasticsearchTranslator(Visitor):"""Translate `Elasticsearch` internal query language elements to valid filters."""allowed_comparators=[Comparator.EQ,Comparator.GT,Comparator.GTE,Comparator.LT,Comparator.LTE,Comparator.CONTAIN,Comparator.LIKE,]"""Subset of allowed logical comparators."""allowed_operators=[Operator.AND,Operator.OR,Operator.NOT]"""Subset of allowed logical operators."""def_format_func(self,func:Union[Operator,Comparator])->str:self._validate_func(func)map_dict={Operator.OR:"should",Operator.NOT:"must_not",Operator.AND:"must",Comparator.EQ:"term",Comparator.GT:"gt",Comparator.GTE:"gte",Comparator.LT:"lt",Comparator.LTE:"lte",Comparator.CONTAIN:"match",Comparator.LIKE:"match",}returnmap_dict[func]
[docs]defvisit_comparison(self,comparison:Comparison)->Dict:# ElasticsearchStore filters require to target# the metadata object fieldfield=f"metadata.{comparison.attribute}"is_range_comparator=comparison.comparatorin[Comparator.GT,Comparator.GTE,Comparator.LT,Comparator.LTE,]ifis_range_comparator:value=comparison.valueifisinstance(comparison.value,dict)and"date"incomparison.value:value=comparison.value["date"]return{"range":{field:{self._format_func(comparison.comparator):value}}}ifcomparison.comparator==Comparator.CONTAIN:return{self._format_func(comparison.comparator):{field:{"query":comparison.value}}}ifcomparison.comparator==Comparator.LIKE:return{self._format_func(comparison.comparator):{field:{"query":comparison.value,"fuzziness":"AUTO"}}}# we assume that if the value is a string,# we want to use the keyword fieldfield=f"{field}.keyword"ifisinstance(comparison.value,str)elsefieldifisinstance(comparison.value,dict):if"date"incomparison.value:comparison.value=comparison.value["date"]return{self._format_func(comparison.comparator):{field:comparison.value}}