Узел Elasticsearch js на момент времени search_phase_execution_exception

          const body = {
  query: {
    geo_shape: {
      geometry: {
        relation: 'within',
        shape: {
          type: 'polygon',
          coordinates: [$polygon],
        },
      },
    },
  },
  pit: {
    id:  "t_yxAwEPZXNyaS1wYzYtMjAxN3IxFjZxU2RBTzNyUXhTUV9XbzhHSk9IZ3cAFjhlclRmRGFLUU5TVHZKNXZReUc3SWcAAAAAAAALmpMWQkNwYmVSeGVRaHU2aDFZZExFRjZXZwEWNnFTZEFPM3JReFNRX1dvOEdKT0hndwAA",
    keep_alive: "1m",
  },
};

Запрос не выполняется с search_phase_execution_exception в onBody. Запрос без ямы работает нормально, но необходимо получить более 10000 совпадений.

3 ответа

Что ж, использование PIT в клиенте NodeJS ElasticSearch неясно или, по крайней мере, плохо документировано. Вы можете создать PIT с помощью клиента, например:

      const pitRes = await elastic.openPointInTime({
  index: index,
  keep_alive: "1m"
});

pit_id = pitRes.body.id;

Но нет возможности использовать этот pit_id в методе поиска, и он не задокументирован должным образом: S

НО, вы можете использовать API прокрутки следующим образом:

      const scrollSearch =  await elastic.helpers.scrollSearch({
index: index,
body: {
  "size": 10000,
  "query": {
    "query_string": {
      "fields": [ "vm_ref", "org", "vm" ],
      "query": organization + moreQuery
    },
  "sort": [
    { "utc_date": "desc" }
  ]
  }
}});

А затем прочтите результаты следующим образом:

      let res = [];

try {
  for await (const result of scrollSearch) {
    res.push(...result.body.hits.hits);
  }
} catch (e) {
  console.log(e);
}

Я знаю, что это не точный ответ на ваш вопрос, но надеюсь, что это поможет;)

Использование момента времени для разбивки на страницы результатов поиска теперь задокументировано в ElasticSearch. Вы можете найти более или менее подробные объяснения здесь: Пагинация результатов поиска

Я подготовил пример, который может дать представление о том, как реализовать рабочий процесс, описанный в документации:

      async function searchWithPointInTime(cluster, index, chunkSize, keepAlive) {
    if (!chunkSize) {
        chunkSize = 5000;
    }
    if (!keepAlive) {
        keepAlive = "1m";
    }

    const client = new Client({ node: cluster });
    let pointInTimeId = null;
    let searchAfter = null;

    try {
        // Open point in time
        pointInTimeId = (await client.openPointInTime({ index, keep_alive: keepAlive })).body.id;

        // Query next chunk of data
        while (true) {
            const size = remained === null ? chunkSize : Math.min(remained, chunkSize);
            const response = await client.search({
                // Pay attention: no index here (because it will come from the point-in-time)
                body: {
                    size: chunkSize,
                    track_total_hits: false, // This will make query faster
                    query: {
                        // (1) TODO: put any filter you need here (instead of match_all)
                        match_all: {},
                    },
                    pit: {
                        id: pointInTimeId,
                        keep_alive: keepAlive,
                    },
                    // Sorting should be by _shard_doc or at least include _shard_doc
                    sort: [{ _shard_doc: "desc" }],
                    // The next parameter is very important - it tells Elastic to bring us next portion
                    ...(searchAfter !== null && { search_after: [searchAfter] }),
                },
            });

            const { hits } = response.body.hits;
            if (!hits || !hits.length) {
                break; // No more data
            }

            for (hit of hits) {
                // (2) TODO: Do whatever you need with results
            }

            // Check if we done reading the data
            if (hits.length < size) {
                break; // We finished reading all data
            }

            // Get next value for the 'search after' position 
            // by extracting the _shard_doc from the sort key of the last hit
            searchAfter = hits[hits.length - 1].sort[0];
        }
    } catch (ex) {
        console.error(ex);
    } finally {
        // Close point in time
        if (pointInTime) {
            await client.closePointInTime({ body: { id: pointInTime } });
        }
    }
}

Хотя я не вижу проблемы с вашим запросом, вот полный пример, который мне подходит:

Другие вопросы по тегам