Подтвердить что ты не робот

ELK: Как получить более 10000 результатов/событий в Elastic-search

Проблема: получение более 10 000 результатов в упругом поиске с помощью поиска по GET/поисковому запросу.

GET hostname:port /myIndex/_search { 
    "size": 10000,
    "query": {
        "term": { "field": "myField" }
    }
}

Я использовал параметр размера, зная, что:

index.max_result_window = 100000

Но если мой запрос имеет размер 650 000 документов, например или даже больше, как я могу получить все результаты в одном GET?

Я читал о SCROLL, FROM-TO и API PAGINATION, но все они никогда не доставляют больше 10K.

Это пример с Elasticsearch Forum, который я использую:

GET /_search?scroll=1m

Кто-нибудь может привести пример, где вы можете получить все документы для поискового запроса GET?

Большое спасибо.

4b9b3361

Ответ 1

Прокрутка - это способ пойти, если вы хотите получить большое количество документов, в том смысле, что это путь к пределу по умолчанию 10000, который можно повысить.

Первый запрос должен указать запрос, который вы хотите создать, и параметр scroll с продолжительностью до истечения времени поиска (1 минута в примере ниже)

POST /index/type/_search?scroll=1m
{
    "size": 1000,
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    }
}

В ответе на этот первый вызов вы получите _scroll_id, который необходимо использовать для совершения второго вызова:

POST /_search/scroll 
{
    "scroll" : "1m", 
    "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==" 
}

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

Итак, в псевдокоде он выглядит примерно так:

# first request
response = request('POST /index/type/_search?scroll=1m')
docs = [ response.hits ]
scroll_id = response._scroll_id

# subsequent requests
while (true) {
   response = request('POST /_search/scroll', scroll_id)
   docs.push(response.hits)
   scroll_id = response._scroll_id
}

Ответ 2

Другой вариант - это тег search_after. Присоединяясь к механизму сортировки, вы можете сохранить свой последний элемент в первом возврате, а затем запросить результаты после этого последнего элемента.

    GET twitter/_search
    {
     "size": 10,
        "query": {
            "match" : {
                "title" : "elasticsearch"
            }
        },
        "search_after": [1463538857, "654323"],
        "sort": [
            {"date": "asc"},
            {"_id": "desc"}
        ]
    }

Работал на меня. Но до сих пор получить более 10.000 документов не так-то просто.

Ответ 3

Пример прокрутки nodeJS с использованием elascticsearch:

const elasticsearch = require('elasticsearch');
const elasticSearchClient = new elasticsearch.Client({ host: 'esURL' });

async function getAllData(query) {
  const result = await elasticSearchClient.search({
    index: '*',
    scroll: '10m',
    size: 10000,
    body: query,
  });

  const retriever = async ({
    data,
    total,
    scrollId,
  }) => {
    if (data.length >= total) {
      return data;
    }

    const result = await elasticSearchClient.scroll({
      scroll: '10m',
      scroll_id: scrollId,
    });

    data = [...data, ...result.hits.hits];

    return retriever({
      total,
      scrollId: result._scroll_id,
      data,
    });
  };

  return retriever({
    total: result.hits.total,
    scrollId: result._scroll_id,
    data: result.hits.hits,
  });
}

Ответ 4

Я могу предложить лучший способ сделать это. Я полагаю, вы пытаетесь получить более 10000 записей. Попробуйте следующий способ, и вы также получите миллионы записей.

  1. Определите своего клиента.

    client = Elasticsearch(['http://localhost:9200'])
    
  2. search = Search(using=client)

  3. Проверьте общее количество просмотров.

    results = search.execute()
    results.hits.total
    
  4. s = Search(using=client)

  5. Запишите ваш запрос.

    s = s.query(..write your query here...)
    
  6. Скопируйте данные в кадр данных с помощью сканирования. Сканирование сбросит все данные в ваш фрейм данных, даже если они исчисляются миллиардами, поэтому будьте осторожны.

    results_df = pd.DataFrame((d.to_dict() for d in s.scan()))
    
  7. Посмотрите на свой фрейм данных.

    results_df
    
  8. Если вы получаете ошибку с функцией поиска, сделайте следующее:

    from elasticsearch_dsl import Search
    

Ответ 5

Посмотрите на документацию search_after

Пример запроса в виде хэша в Ruby:

query = {
  size: query_size,
  query: {
    multi_match: {
      query: "black",
      fields: [ "description", "title", "information", "params" ]
    }
  },
  search_after: [after],
  sort: [ {id: "asc"} ]

}

Ответ 6

При наличии более 10000 результатов единственный способ получить остальное - разделить запрос на несколько более уточненных запросов с более строгими фильтрами, чтобы каждый запрос возвращал менее 10000 результатов. А затем объедините результаты запроса, чтобы получить полный набор результатов.

Это ограничение в 10000 результатов применяется к веб-службам, которые поддерживаются индексом ElasticSearch, и, тем не менее, нет никакого способа обойти это, веб-служба должна быть переопределена без использования ElasticSearch.

Ответ 7

Ну вот:

GET /_search
{
  "size": "10000",
    "query": {
        "match_all": {"boost" : "1.3" }
    }
}

Но в основном мы должны избегать такого подхода, чтобы получать огромное количество документов одновременно, поскольку это может увеличить использование данных и накладные расходы.