from typing import List from enum import Enum class SimpleQueryStrategy: def query(self, query: str, fields: List[str]) -> dict: return {"query_string": {"query": query, "fields": fields if fields else ["*"]}} class FuzzyQueryStrategy: def __init__(self, fuzziness: str = "AUTO"): self.fuzziness = fuzziness def query(self, query: str, fields: List[str]) -> dict: return { "multi_match": { "query": query, "operator": "and", "fuzziness": self.fuzziness, "fields": fields if fields else ["*"], } } class PhraseQueryStrategy: """ Phrase Query is convenient for exact phrase match Phrase Prefix Query maybe used for autocomplete as well, but not encouraged https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query-phrase-prefix.html """ def __init__(self, prefix: bool = False): self.mutli_match_type = "phrase_prefix" if prefix else "phrase" def query(self, query: str, fields: List[str]) -> dict: return {"multi_match": {"query": query, "type": self.mutli_match_type, "fields": fields if fields else ["*"]}} class QueryStrategyType(Enum): SIMPLE_QUERY = SimpleQueryStrategy() MULTIMATCH_FUZZY_QUERY = FuzzyQueryStrategy() MULTIMATCH_PHRASE_QUERY = PhraseQueryStrategy() def query(self): klass = self.value return klass.query