wake-up-neo.com

ELK: Wie kann ich mehr als 10000 Ergebnisse/Ereignisse in der Elastic-Suche abrufen?

Problem: Abrufen von mehr als 10.000 Ergebnissen in der elastischen Suche über die Suche in einer GET/Suchabfrage.

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

Ich habe die Größenoption verwendet und wusste, dass:

index.max_result_window = 100000

Wenn jedoch meine Abfrage beispielsweise die Größe von 650.000 Dokumenten oder sogar mehr hat, wie kann ich dann alle Ergebnisse in einem GET abrufen?

Ich habe über SCROLL, FROM-TO und die PAGINATION-API gelesen, aber alle liefern niemals mehr als 10 KB.

Dies ist das Beispiel aus dem Elasticsearch Forum, das ich verwendet habe:

GET /_search?scroll=1m

Kann jemand ein Beispiel geben, in dem Sie alle Dokumente für eine GET-Suchabfrage abrufen können?

Vielen Dank.

13
Franco

Scroll ist der Weg, wenn Sie eine große Anzahl von Dokumenten abrufen möchten, und zwar in dem Sinne, dass sie die 10000-Standardgrenze überschreitet, die angehoben werden kann.

Die erste Anforderung muss die gewünschte Abfrage und den Parameter scroll mit duration angeben, bevor der Suchkontext abläuft (1 Minute im Beispiel unten).

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

In der Antwort auf diesen ersten Anruf erhalten Sie einen _scroll_id, den Sie für den zweiten Anruf verwenden müssen:

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

In jeder weiteren Antwort erhalten Sie einen neuen _scroll_id, den Sie für den nächsten Anruf verwenden müssen, bis Sie die benötigte Menge an Dokumenten abgerufen haben.

Im Pseudocode sieht das also ungefähr so ​​aus:

# 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
}
18
Val

bitte schön:

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

Wir sollten diesen Ansatz jedoch größtenteils vermeiden, um eine große Menge von Dokumenten gleichzeitig abzurufen, da dies die Datennutzung und den Overhead erhöhen kann.

1
Ajinkya Bhabal

Eine weitere Option ist das search_after Tag. Zusammen mit einem Sortiermechanismus können Sie Ihr letztes Element in der ersten Zeile speichern und dann nach Ergebnissen fragen, die auf dieses letzte Element folgen.

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

Arbeitete für mich. Bis jetzt ist es jedoch nicht einfach, mehr als 10.000 Dokumente zu erhalten.

0
Dan

Ich kann einen besseren Weg vorschlagen, dies zu tun. Ich denke, Sie versuchen, mehr als 10.000 Datensätze zu bekommen. Versuchen Sie es wie folgt und Sie werden auch Millionen von Datensätzen erhalten.

  1. Definieren Sie Ihren Kunden.

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

  3. Überprüfen Sie die Gesamtzahl der Treffer.

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

  5. Notieren Sie Ihre Anfrage.

    s = s.query(..write your query here...)
    
  6. Dump die Daten in einen Datenrahmen mit Scan. Scan speichert alle Daten in Ihrem Datenrahmen, auch wenn sie in Milliardenhöhe vorliegen. Seien Sie also vorsichtig.

    results_df = pd.DataFrame((d.to_dict() for d in s.scan()))
    
  7. Schauen Sie sich Ihren Datenrahmen an.

    results_df
    
  8. Wenn Sie eine Fehlermeldung mit der Suchfunktion erhalten, gehen Sie wie folgt vor:

    from elasticsearch_dsl import Search
    
0
ak3191

nodeJS scroll Beispiel mit 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,
  });
}
0
zooblin

Schauen Sie sich search_after documentation an

Beispielabfrage als Hash in Ruby:

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

}

Wenn mehr als 10000 Ergebnisse vorliegen, besteht die einzige Möglichkeit, den Rest zu erhalten, darin, Ihre Abfrage in mehrere, verfeinerte Abfragen mit strengeren Filtern aufzuteilen, sodass jede Abfrage weniger als 10000 Ergebnisse zurückgibt. Kombinieren Sie anschließend die Abfrageergebnisse, um die vollständige Zielergebnismenge zu erhalten.

Diese Beschränkung auf 10000 Ergebnisse gilt für Webservices, die vom ElasticSearch-Index unterstützt werden, und es führt kein Weg daran vorbei, dass der Webservice ohne die Verwendung von ElasticSearch erneut implementiert werden muss.

0
Tenusha