from dataclasses import dataclass from typing import List from api import elastic_search from db import db # from app import app import traceback from utils.elastic_search.query import ElasticSearchQuery from utils.elastic_search.query_strategy import QueryStrategyType from urllib3.exceptions import ConnectionError, NewConnectionError @dataclass class SearchResult: ids: List[int] total: int def add_model(model): try: payload = {} table_index = model.elastic_index() for data in model.__searchable__.keys(): payload[data] = getattr(model, data) elastic_search.index(index=table_index, id=model.id, body=payload) elastic_search.indices.refresh(index=table_index, ignore_unavailable=True) except (NewConnectionError, ConnectionError) as error: from app import app app.logger.error("Elastic Search Error: add_model ", f"{error}\n{traceback.format_exc()}") def add_models(model_class, models): try: table_index = model_class.elastic_index() for model in models: elastic_search.index(index=table_index, id=model.id, body=model.es_payload()) elastic_search.indices.refresh(index=table_index, ignore_unavailable=True) except (NewConnectionError, ConnectionError) as error: from app import app app.logger.error("Elastic Search Error: add_model ", f"{error}\n{traceback.format_exc()}") def remove_model(model: db.Model): try: table_index = model.elastic_index() if elastic_search.exists(index=table_index, id=model.id): elastic_search.delete(index=table_index, id=model.id) except (NewConnectionError, ConnectionError) as error: from app import app app.logger.error("Elastic Search Error: remove_model ", f"{error}\n{traceback.format_exc()}") def query_model( model: str, query: str, fields: List[str] = None, page: int = None, per_page: int = None, query_strategy: QueryStrategyType = QueryStrategyType.MULTIMATCH_FUZZY_QUERY, ) -> SearchResult: try: body = ElasticSearchQuery.default_search(query=query, fields=fields, strategy=query_strategy) if page and per_page: offset = (page - 1) * per_page body.update({"from": offset, "size": per_page}) search = elastic_search.search(index=model, body=body) ids = [int(hit["_id"]) for hit in search["hits"]["hits"]] return SearchResult(ids=ids, total=search["hits"]["total"]) except (NewConnectionError, ConnectionError) as error: from app import app app.logger.error("Elastic Search Error: query_model ", f"{error}\n{traceback.format_exc()}") return SearchResult(ids=[], total=0)