Как удалить документы из Elasticsearch

Я не могу найти ни одного примера удаления документов из Elasticsearch в Python. То, что я уже видел, - это определение функций delete и delete_by_query. Но по какой-то причине документация не дает даже микроскопического примера использования этих функций. Единый список параметров не говорит мне слишком много, если я не знаю, как правильно передать их в вызов функции. Итак, допустим, я только что вставил один новый документ примерно так:

doc = {'name':'Jacobian'}
db.index(index="reestr",doc_type="some_type",body=doc)

Кто в мире знает, как я могу теперь удалить этот документ, используя delete и delete_by_query?

Ответ 1

Поскольку вы не указываете идентификатор документа при индексировании своего документа, вам необходимо получить идентификатор автоматически сгенерированного документа из возвращаемого значения и удалить в соответствии с идентификатором. Или вы можете сами определить идентификатор, попробуйте следующее:

 db.index(index="reestr",doc_type="some_type",id=1919, body=doc)

 db.delete(index="reestr",doc_type="some_type",id=1919)

В другом случае вам нужно посмотреть в возвращаемое значение;

 r = db.index(index="reestr",doc_type="some_type", body=doc)
 # r = {u'_type': u'some_type', u'_id': u'AU36zuFq-fzpr_HkJSkT', u'created': True, u'_version': 1, u'_index': u'reestr'}

 db.delete(index="reestr",doc_type="some_type",id=r['_id'])

Другой пример для delete_by_query. Скажем, добавив несколько документов с помощью name= "Якобиан", выполните следующие действия, чтобы удалить все документы с помощью name= "Якобиан":

 db.delete_by_query(index='reestr',doc_type='some_type', q={'name': 'Jacobian'})

Ответ 2

API-интерфейс Delete-By-Query был удален из ядра ES в версии 2 по нескольким причинам. Эта функция стала плагином. Вы можете найти более подробную информацию здесь:

Почему Delete-By-Query является плагином

Удалить по плану запроса

Поскольку я не хотел добавлять другую зависимость (потому что мне нужно это позже, чтобы запустить изображение докера), я написал собственную функцию, решая эту проблему. Мое решение состоит в поиске всех котировок с указанным индексом и типом. После этого я удаляю их с помощью Bulk API:

def delete_es_type(es, index, type_):
    try:
        count = es.count(index, type_)['count']
        response = es.search(
            index=index,
            filter_path=["hits.hits._id"],
            body={"size": count, "query": {"filtered" : {"filter" : {
                  "type" : {"value": type_ }}}}})
        ids = [x["_id"] for x in response["hits"]["hits"]]
        if len(ids) > 0:
            return
        bulk_body = [
            '{{"delete": {{"_index": "{}", "_type": "{}", "_id": "{}"}}}}'
            .format(index, type_, x) for x in ids]
        es.bulk('\n'.join(bulk_body))
        # es.indices.flush_synced([index])
    except elasticsearch.exceptions.TransportError as ex:
        print("Elasticsearch error: " + ex.error)
        raise ex

Я надеюсь, что это поможет будущим гуглерам;)

Ответ 3

Можно также сделать что-то вроде этого:

def delete_by_ids(index, ids):
    query = {"query": {"terms": {"_id": ids}}}
    res = es.delete_by_query(index=index, body=query)
    pprint(res)

# Pass index and list of id that you want to delete.
delete_by_ids('my_index', ['test1', 'test2', 'test3'])

Который будет выполнять операцию удаления больших объемов данных