[JAVA] Erstellen einer Elasticsearch Plugin Series (2) Suche

In dieser Serie werde ich die grundlegende Methode zum Schreiben eines Plugins für Elastic Search erläutern. Letztes Mal erklärte, wie man ein Plugin grob erstellt, indem man ein einfaches Plugin erstellt, das Hello World anzeigt. Teil 2 erstellt ein Plugin, das einfache Suchanfragen akzeptiert. Die erstellte Quelle finden Sie unter github (die vorherige wurde geändert).

Zweck

Elasticsearch kann die meisten Suchanforderungen mit JSON-formatierten Anforderungen verarbeiten. Wenn dies jedoch Standard ist, werden Wartungsfunktionen wie das Löschen von Indizes angezeigt, und es ist nicht wünschenswert, direkt über das WEB auf Elasticsearch zuzugreifen. Daher wird Elasticsearch normalerweise als Bild wie eine Datenbank in Form von WEB → AP-Server → Elasticsearch verwendet. Darüber hinaus kann Elasticsearch die Verfügbarkeit mithilfe eines Clusters problemlos garantieren, der AP-Server muss jedoch die Verfügbarkeit nach einer ursprünglichen Methode gewährleisten. Dies stellt eine hohe Betriebslast dar und erhöht die Anzahl der Überwachungsziele. Wenn Elasticsearch die Funktion eines AP-Servers haben kann, sollte es möglich sein, eine Anwendung zu erstellen, die einige Geschäftsanforderungen erfüllt, nur durch die Verwaltung von Elasticsearch. Ab diesem Zeitpunkt werden wir überprüfen, wie viel mit dem Plug-In getan werden kann, mit dem Ziel, dass Elasticsearch über einen AP-Server verfügt. Zunächst erstellen wir eine REST-API, die eine Volltextsuche im Feld "Text" eines Dokuments mit Abfrageparametern (Text) durchführt.

Implementierungsübersicht

Das Framework des Plug-Ins ist das gleiche wie beim letzten Mal. Der Unterschied besteht darin, dass RestHandler eine "Suchanforderung" an den Indexknoten sendet. Ich generiere eine "Suchanforderung" für einen Indexknoten aus einer REST-Anforderung, kann aber leicht eine "Suchanforderung" aus einer JSON-formatierten REST-Anforderung von Elasticsearch generieren. Dieses Mal werde ich es benutzen.

Betriebsumgebung

Es ist fast das gleiche wie beim letzten Mal, aber ich habe die 6.1-Version von Gradle verwendet, weil sie nicht verfügbar war.

Notation im Artikel

Vorbereitungen

--Installieren Sie Elasticsearch OSS-Version. Erweitern Sie auf [ELASTICSEARCH_DIR].

Projektvorbereitung

Letztes Mal Verwenden Sie das erstellte Projekt.

Vorbereitung der Plug-In-Quelle

Erstellen Sie ein Dienstprogramm zum Generieren von JSON-formatierten Anforderungen.

Es ist einfacher zu sehen, wenn Vorlagen aus einer Datei geladen werden, aber Elasticsearch hat nur relativ eingeschränkten Zugriff auf die Standard-APIs von Java über Plugins. Sie können es in den Einstellungen zugänglich machen, aber dieses Mal werden wir es in die Quelle einbetten. Ich werde ab dem nächsten Mal über die Lockerung der Zugriffsbeschränkungen auf die API schreiben.

QueryTemplate.java


package taka8.elasticsearch.rest;

public class QueryTemplate {

//	{
//	  "query" : {
//	    "match" : {
//	      "text" : {
//	        "query" : "[[text]]",
//	        "operator" : "and"
//	      }
//	    }
//	  }
//	}
	private static final String TEXT_ONLY = "{\"query\":{\"match\":{\"text\":{\"query\":\"[[text]]\",\"operator\":\"and\"}}}}";

	public static String getTextOnly(String text) {
		return QueryTemplate.TEXT_ONLY.replace("[[text]]", text);
	}
}

Erstellen Sie einen RestHandler

TextOnlySearchAction.java


package taka8.elasticsearch.rest;

import static org.elasticsearch.rest.RestRequest.Method.GET;

import java.io.IOException;

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.xcontent.DeprecationHandler;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.action.RestStatusToXContentListener;
import org.elasticsearch.search.builder.SearchSourceBuilder;

//RestHandler, der die REST-API akzeptiert, kann einfach durch Erben von BaseRestHandler erstellt werden
public class TextOnlySearchAction extends BaseRestHandler {

	public TextOnlySearchAction(final RestController controller) {
		assert controller != null;
		//Definieren Sie den Pfad zum Akzeptieren der Anforderung.
		controller.registerHandler(GET, "/{index}/search_text", this);
	}

	//Definieren Sie den Namen von RestHandler.
	//Machen Sie den Namen für die Menschen leicht sichtbar.
	//Wird in APIs verwendet, die die Verwendung zurückgeben
	@Override
	public String getName() {
		return "search_text_action";
	}

	@Override
	protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
		SearchRequest searchRequest = new SearchRequest();
		request.withContentOrSourceParamParserOrNull(parser -> _parseSearchRequest(searchRequest, request, parser));
		return channel -> {
			//Generieren Sie einen Listener, der aus den Suchergebnissen einen REST-API-Rückgabewert erstellt.
			//Hier ist es ein Standard-Listener, der das Suchergebnis so zurückgibt, wie es ist.
			RestStatusToXContentListener<SearchResponse> listener = new RestStatusToXContentListener<>(channel);
			//Wirf eine Anfrage an den Indexknoten. Elasticsearch garantiert Suchleistung und -verfügbarkeit, indem der Index aufgeteilt und auf mehreren Knoten angeordnet wird.
			//Daher ist es erforderlich, eine Anforderung von dem Knoten, der die REST-Anforderung akzeptiert, an den Knoten zu senden, der die Suche tatsächlich durchführt.
			client.search(searchRequest, listener);
		};
	}

	//Initialisieren Sie die Suchanforderung über die REST-Eingabe an den Indexknoten.
	private void _parseSearchRequest(SearchRequest searchRequest, RestRequest request,
			XContentParser requestContentParser) throws IOException {
		if (searchRequest.source() == null) {
			searchRequest.source(new SearchSourceBuilder());
		}
		//Generieren Sie eine Elasticsearch JSON-formatierte Suchanforderung aus dem Textparameter der Abfrage.
		String source = QueryTemplate.getTextOnly(request.param("text"));
		//Parser für Suchanfragen im JSON-Format.
		XContentParser parser = XContentType.JSON.xContent().createParser(request.getXContentRegistry(),
				DeprecationHandler.THROW_UNSUPPORTED_OPERATION, source);
		searchRequest.source().parseXContent(parser);
		searchRequest.indices(Strings.splitStringByCommaToArray(request.param("index")));
	}

}

Funktionsprüfung

Bereitstellen

Befolgen Sie die Anweisungen zum Überprüfen des Betriebs von Letztes Mal, um Elasticsearch zu installieren.

Registrierung der zu durchsuchenden Dokumente

POSTEN Sie das Dokument im JSON-Format mit einem Tool, das eine POST-Anforderung ausgeben kann, an die folgende URL. http://localhost:9200/test/_bulk

{"create": {"_id": "1"}}
{"text": "Steig ins Auto"}
{"create": {"_id": "2"}}
{"text": "Steig vom Fahrrad"}

Bildschirmprüfung

Greifen Sie in Ihrem Browser auf "http : // localhost: 9200 / test / search_text? Text = car" zu und überprüfen Sie, ob Dokumente mit "car" wie unten gezeigt durchsucht werden (die folgenden Formate JSON). tun).

{
  "took": 43,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 1.0921589,
    "hits": [
      {
        "_index": "test",
        "_type": "_doc",
        "_id": "1",
        "_score": 1.0921589,
        "_source": {
          "text": "Steig ins Auto"
        }
      }
    ]
  }
}

Nachwort

Ich habe eine Anfrage im JSON-Format von einer Abfrage mit einem Plug-In gestellt und bestätigt, dass sie damit korrekt durchsucht werden kann. Dies scheint die Suche mit den üblichen Geschäftsanforderungen zu erfüllen. Versuchen Sie als Nächstes, einen Rückgabewert zu generieren, der Ihren Geschäftsanforderungen entspricht.

Recommended Posts

Erstellen einer Elasticsearch Plugin Series (2) Suche
Elastic Search Indexerstellung aus Java
[Rails] Erstellen eines Suchfelds
Erstellen Sie Ihr eigenes Elasticsearch-Plugin