Как сохранить документ в формате json с использованиемasticsearch-dsl - PullRequest
0 голосов
/ 12 февраля 2020

Я пытаюсь обновить существующий конвейер данных эластичного поиска и хотел бы использовать эластичный поиск-dsl более полно. В текущем процессе мы создаем документ как json объект, а затем используем запросы, чтобы поместить объект в соответствующий индекс эластичного поиска.

Теперь я хотел бы использовать метод сохраненияasticsearch-dsl, но у меня не получается чтобы понять, как я могу это сделать, когда мой объект или документ построен как json.

Текущий процесс:

//import_script.py

index = 'objects'
doc = {"title": "A title", "Description": "Description", "uniqueID": "1234"}
doc_id = doc["uniqueID"]
elastic_url = 'http://elastic:changeme@localhost:9200/' + index + '/_doc/ + doc_id

api = ObjectsHandler()
api.put(elastic_url, doc)


//objects_handler.py

class ObjectsHandler():
     def put(self, url, object):
        result = requests.put(url, json=object)
        if result.status_code != requests.codes.ok:
            print(result.text)
            result.raise_for_status()

Вместо того, чтобы использовать этот метод PUT, я бы хотел использовать функциональность Document.save доступна в DSL, но я не могу перевести примеры в документации api для моего варианта использования.

Я изменил свой ObjectsHandler, чтобы он мог создавать индекс объектов:

//objects_handler.py

es = Elasticsearch([{'host': 'localhost', 'port': 9200}],
                   http_auth='elastic:changeme')

connections.create_connection(es)

class Object(Document):
    physicalDescription = Text()
    title = Text()
    uniqueID = Text()

    class Index:
        name = 'objects'
        using = es

class ObjectsHandler():

   def init_mapping(self, index):
        Object.init(using=es, index=index)

Это успешно создает индекс, когда я вызываю api.init_mapping(index) из скрипта импортера.

Документация имеет это в качестве примера для сохранения отдельных документов, где Article - это эквивалентен моему классу Object:

# create and save and article
article = Article(meta={'id': 42}, title='Hello world!', tags=['test'])
article.body = ''' looong text '''
article.published_from = datetime.now()
article.save()

Могу ли я использовать эту методологию, но сохранить свою предварительно построенную json объект делать c, а не указывать отдельные атрибуты? Мне также нужно иметь возможность указать, что идентификатором документа является do c uniqueID.

Я расширил свой ObjectsHandler для включения метода save_do c:

def save_doc(self, document, doc_id, index):
        new_obj = Object(meta={'id': doc_id}, 
                  title="hello", uniqueID=doc_id,
                  physicalDescription="blah")
        new_obj.save()

который успешно сохраняет объект с uniqueID в качестве идентификатора, но я не могу использовать объект json, переданный методу как document.

1 Ответ

0 голосов
/ 12 февраля 2020

Я добился некоторого успеха в этом, используя набор помощников по работе сasticsearch.py, а не эластичный поиск-DSL. Следующие ресурсы были очень полезны:

В моем вопросе я имел в виду:

doc = {"title": "A title", "Description": "Description", "uniqueID": "1234"}

У меня фактически есть массив или список из 1 или более документов, например:

documents = [{"title": "A title", "Description": "Description", "uniqueID": "1234"}, {"title": "Another title", "Description": "Another description", "uniqueID": "1235"}]

Я создаю тело для массового импорта и добавляю id:

for document in documents:
   bulk_body.append({'index': {'_id': document["uniqueID"]}})
   bulk_body.append(document)

, затем выполните мой новый вызов метода helpers.bulk:

api_handler.save_docs(bulk_body, 'objects')

с моим файлом objects_handler.py, похожим на:

//objects_handler.py
from elasticsearch.helpers import bulk

es = Elasticsearch([{'host': 'localhost', 'port': 9200}],
                   http_auth='elastic:changeme')

connections.create_connection(es)

class Object(Document):
    physicalDescription = Text()
    title = Text()
    uniqueID = Text()

    class Index:
        name = 'objects'
        using = es

class ObjectsHandler():

   def init_mapping(self, index):
        Object.init(using=es, index=index)

   def save_docs(self, docs, index):
        print("Attempting to index the list of docs using helpers.bulk()")
        resp = es.bulk(index='objects', body=docs)
        print("helpers.bulk() RESPONSE:", resp)
        print("helpers.bulk() RESPONSE:", json.dumps(resp, indent=4))

Это работает для отдельных документов в формате json или нескольких документов.

...