Ich habe eine Datenbank in elastischer Suche und möchte alle Datensätze auf meiner Website-Seite abrufen. Ich schrieb eine Bean, die sich mit dem elastischen Suchknoten verbindet, Datensätze durchsucht und eine Antwort zurückgibt. Mein einfacher Java-Code, der die Suche durchführt, ist:
SearchResponse response = getClient().prepareSearch(indexName).setTypes(typeName) .setQuery(queryString("*:*")).setExplain(true).execute().actionGet();
Aber elasticsearch hat die Standardgröße auf 10 gesetzt und ich habe 10 Treffer als Antwort. Es gibt mehr als 10 Datensätze in meiner Datenbank. Wenn ich Größe auf Integer.MAX_VALUE
einstelle, wird meine Suche sehr langsam und das ist nicht was ich will.
Wie kann ich alle Datensätze in einer Aktion in einer akzeptablen Zeitspanne abrufen, ohne die Antwortgröße festzulegen?
Die aktuellste Antwort mit dem höchsten Rang funktioniert, aber es muss die gesamte Ergebnisliste in den Speicher geladen werden, was zu Speicherproblemen bei großen Ergebnismengen führen kann und in jedem Fall unnötig ist.
Ich habe eine Java-Klasse erstellt, die eine nette Iterator
über SearchHit
s implementiert, die es ermöglicht, alle Ergebnisse zu durchlaufen. Intern behandelt es Seitenumbrüche, indem es Abfragen ausgibt, die das Feld from:
enthalten, und es speichert nur eine Seite der Ergebnisse im Speicher .
Verwendung:
%Vor% Beachten Sie, dass Sie beim Erstellen von SearchRequestBuilder
nicht setFrom(int)
aufrufen müssen, da dies von SearchHitIterator
interaktiv erledigt wird. Wenn Sie die Größe einer Seite angeben möchten (d. H. Die Anzahl der Suchtreffer pro Seite), können Sie setSize(int)
aufrufen, andernfalls wird der Standardwert von ElasticSearch verwendet.
SearchHitIterator:
%Vor%Wenn ich bedenke, wie praktisch es ist, eine solche Klasse zu haben, frage ich mich, warum der Java-Client von ElasticSearch nicht etwas Ähnliches bietet.
Sie müssen die Anzahl der zurückgegebenen Ergebnisse gegen die Zeit abwägen, die der Benutzer warten soll, und die Menge des verfügbaren Serverspeichers. Wenn Sie 1.000.000 Dokumente indiziert haben, gibt es keine realistische Möglichkeit, alle Ergebnisse in einer Anfrage abzurufen. Ich nehme an, dass Ihre Ergebnisse für einen Benutzer sind. Sie müssen überlegen, wie das System unter Last funktioniert.
Wenn Sie sich hauptsächlich auf den Export aller Datensätze konzentrieren, sollten Sie sich für eine Lösung entscheiden, bei der keine Sortierung erforderlich ist, da das Sortieren teuer ist. Sie können den Scan-und Scroll-Ansatz mit ElasticsearchCRUD verwenden, wie beschrieben hier .
1. Legen Sie die maximale Größe fest, z. B .: MAX_INT_VALUE;
private static final int MAXSIZE = 1000000;
@Override Die öffentliche Liste getAllSaleCityByCity (int cityId) gibt die Ausnahme {
aus %Vor%2.zählen Sie das ES, bevor Sie suchen
%Vor%int size = (int) countResponse.getCount (); // das ist die gewünschte Größe;
dann können Sie
%Vor%