import json import logging from pathlib import Path import time from elasticsearch import Elasticsearch from tqdm import tqdm def create_index_elastic_rocks_nn( path: str, logger: logging.Logger | None = None, ): if logger is None: logger = logging.getLogger(__name__) # Подключение к Elasticsearch es = Elasticsearch(hosts='localhost:9200') INDEX_NAME = 'rocks_nn_search_elastic' # Удаление старого индекса, если он существует if es.indices.exists(index=INDEX_NAME): es.indices.delete(index=INDEX_NAME) mapping = { "settings": { "analysis": { "filter": { "custom_stopwords": { "type": "stop", "stopwords": [ "ООО", "ОАО", "НН", "нн", "Перечень", "перечень", "дивизиона", "дивизион", ], } }, "analyzer": { "custom_analyzer": { "type": "custom", "tokenizer": "standard", "filter": [ "lowercase", "custom_stopwords", ], } }, } }, "mappings": { "properties": { "division_name": { "type": "text", "analyzer": "custom_analyzer", "search_analyzer": "custom_analyzer", }, "division_name_2": { "type": "text", "analyzer": "custom_analyzer", "search_analyzer": "custom_analyzer", }, "company_name": { "type": "text", "analyzer": "custom_analyzer", "search_analyzer": "custom_analyzer", }, } }, } # Создание индекса с указанным маппингом es.indices.create(index=INDEX_NAME, body=mapping) for ind, path in tqdm(enumerate(Path(path).iterdir())): # Открываем файл и читаем его содержимое with open(path, 'r', encoding='utf-8') as file: data = json.load(file) # Индексирование документа в Elasticsearch es.index(index=INDEX_NAME, id=ind + 1, body=data) # Подсчет количества документов в индексе count_response = es.count(index=INDEX_NAME) logger.info( f"{ind}, Total documents in '{INDEX_NAME}': {count_response['count']}" ) time.sleep(1.0) if es.indices.exists(index=INDEX_NAME): logger.info(f"Index '{INDEX_NAME}' exists.") # Подсчет количества документов в индексе count_response = es.count(index=INDEX_NAME) logger.info(f"Total documents in '{INDEX_NAME}': {count_response['count']}") query = "Какие РОКС НН входят в состав Норильского дивизиона?" query_ = { "query": { "function_score": { "query": { "multi_match": { "query": f"{query}", "fields": ["division_name", "division_name_2", "company_name"], "fuzziness": "AUTO", "analyzer": "custom_analyzer", } }, "functions": [ { "filter": { "term": {"_id": "3"} # ID документа, который нужно понизить }, "weight": 0.5, # Устанавливает очень низкий вес для этого документа } ], "boost_mode": "multiply", # Сочетание _score и весов } } } # Выполнение поиска в Elasticsearch response = es.search(index=INDEX_NAME, body=query_, size=1) logger.info(f"Number of hits: {response['hits']['total']['value']}") # Вывод результата поиска for hit in response['hits']['hits']: logger.info(hit['_source']) if __name__ == '__main__': path = '/mnt/ntr_work/project/nmd800/data/rocks_nn_card' create_index_elastic_rocks_nn(path)