Vorwort
Im vorherigen Artikel wurden Springboot, Mybatis, Druid und PageHelper integriert und der Betrieb mehrerer Datenquellen implementiert. Dieser Artikel führt hauptsächlich Elastisearch, die beliebteste Suchmaschine, vor und verwendet ihn in Kombination mit Springboot.
Einführung in Elasticsearch
Elasticsearch ist ein Suchserver basierend auf Lucene. Es verkauft tatsächlich Lucene und liefert die Operationsschnittstelle der REST -API. ElasticSearch ist eine hochskalierbare Open-Source-Motor für die Such- und Analyse-Engine, mit der Big Data schnell gespeichert, gesucht und analysiert werden kann.
Die Hauptmerkmale von Elasticsearch: verteilt, hohe Verfügbarkeit, asynchrones Schreiben, Multi-API, Dokumentorientiert.
Elasticsearch-Kernkonzepte: Nahe Echtzeit, Cluster, Knoten (Daten speichern), Index, Shard (Slicing Index Shards), Replicas (Slicing kann mehrere Replikate festlegen). Es kann massive Datenmengen schnell speichern, suchen und analysieren.
Elasticsearch -Anwendungsfälle: Wikipedia, Stapelüberlauf, Github usw.
Springboot integriert Elasticsearch
Bevor wir Springboot zur Integration von Elasticsearch verwenden, sollten wir die Beziehung zwischen ihnen verstehen.
| Spring Boot -Version (x) | Spring Data Elasticsearch Version (Y) | Elasticsearch -Version (Z) |
|---|---|---|
| x <= 1.3.5 | y <= 1.3.4 | z <= 1,7,2* |
| x> = 1.4.x | 2.0.0 <= y <5.0.0 ** | 2.0.0 <= z <5.0.0 ** |
Die Version von Springboot, die wir hier verwenden, ist 1.5.9 und die Version von Elasticsearch ist 2.3.5.
Mit Springboot zur Integration von Elasticsearch wird es im Allgemeinen mit SpringData eingekapselt, und dann erbt die DAO -Schicht -Schnittstelle die ElasticsearchRepository -Klasse. Diese Klasse implementiert viele Methoden, wie die häufig verwendete CRUD -Methode.
Verwendung von Springdata
Treffen Sie zunächst relevante Vorbereitungen vor der Verwendung.
Die Konfiguration von Maven lautet wie folgt:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>1.5.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> <version> 1.9.Release </Version> </abhängig>
Konfiguration von application.Properties
Spring.Data.Elasticsearch.Repositories.enabled = treespring.data.Elasticsearch.cluster-nodes = 127.0.0.1/: 9300
Hinweis: 9300 ist der Port des Java -Clients. 9200 ist eine Schnittstelle, die das Ruhestand von HTTP unterstützt.
Weitere Konfigurationen:
Spring.Data.Elasticsearch.Cluster-Name Elasticsearch-Cluster-Name. (Standard: ElasticSearch)
Spring.Data.Elasticsearch.Cluster-Nodes Liste der Clusterknotenadressen, getrennt durch Kommas. Wenn nicht angegeben, starten Sie einen Client -Knoten.
Spring.Data.Elasticsearch.Propertie wird verwendet, um zusätzliche Eigenschaften des Clients zu konfigurieren.
Spring.Data.Elasticsearch.Repositories.Enabled aktivieren das Elasticsearch -Repository. (Standard: true.)
Code schreiben
Entitätsklasse
@Document (indexname = "userIndex", type = "user") public class User implementiert serialisierbare { / ** * * / private statische endgültige lange Serialversionuid = 1L; / ** Nummer*/ private long id; / ** Name*/ privater Zeichenfolge Name; / ** Alter*/ Private Ganzzahl; / ** Beschreibung*/ private Zeichenfolge Beschreibung; / ** Erstellungszeit*/ private String createTM; // Getter und Setter weggelassen}Bei der Verwendung von SpringData muss es den Indexnamen festlegen und in die Entitätsklasse eingeben. Im Vergleich zu herkömmlichen Datenbanken entspricht sie Bibliotheken und Tabellen.
Es ist zu beachten, dass sowohl Indexname als auch Typ in Kleinbuchstaben sein müssen !!!
DAO -Schicht
Public Interface UserDao erweitert ElasticSearchRepository <User, Long> {}Die DAO -Schicht ist hier relativ einfach, erben Sie einfach die ElasticsarchRepository -Klasse. Die Hauptmethoden sind Speichern, Löschen und Suche. Die Speichernmethode ist sehr wie einfügen und aktualisiert. Wenn es nein gibt, wird es hinzugefügt und wenn es einen gibt, wird es abgedeckt. Die Löschmethode dient hauptsächlich zum Löschen von Daten und Indexbibliotheken. Bei der Suche handelt es sich um eine Abfrage, einschließlich einiger häufig verwendeter Abfragen wie Pagination, Gewichte usw.
Serviceschicht
@ServicePublic Class UserServiceImpl implementiert UserService {@autowired private userDao userDao; @Override public boolean Insert (Benutzerbenutzer) {boolean falg = false; Versuchen Sie {userDao.save (Benutzer); Falg = wahr; } catch (Ausnahme e) {e.printstacktrace (); } return falg; } @Override public List <Benetzbuchs> Search (String SearchContent) {QueryStringQueryBuilder Builder = New QueryStringQueryBuilder (SearchContent); System.out.println ("Abfrageanweisung:"+Builder); Iterable <Benetzwerte> searchResult = userDao.Search (Builder); Iterator <Bers <Unter> iterator = searchResult.Iterator (); List <Benetzbuchs> list = new ArrayList <Bener> (); while (iterator.hasnext ()) {list.add (iterator.next ()); } Rückgabeliste; } @Override public List <Kutzer> Searchuser (Integer pageNumber, Integer pageSize, String SearchContent) {// Paginationsparameter vorlebbar pagable = new pageRequest (pageNumber, pageSize); QueryStringQueryBuilder Builder = new QueryStringQueryBuilder (SearchContent); SearchQuery SearchQuery = New NativeSearchQueryBuilder (). Withpagable (lehnte) .WithQuery (Builder) .build (); System.out.println ("Abfrageanweisung:" + SearchQuery.getQuery (). ToString ()); Page <Bener> SearchPageresults = userDao.Search (SearchQuery); return searchPageresults.getContent (); } @Override public List <Benetzwerte> SearchUserByWeight (String SearchContent) {// Abfrage nach GewichtsfunktionenCorequiller -FunktionenCorequeryBuilder = queryBuilders.FunctionsCoreQuery () .Add (querybuilders.boolquery (). ScoreFunctionBuilders.WeightFactorFunction (10)) .Add (querybuilders.boolQuery (). Sollte (querybuilders.matchQuery ("Beschreibung", SearchContent), ScoreFunctionBuilders.weightFactorFunction (100)). SetMinScore (2); System.out.println ("Abfrageanweisung:" + FunktionenCoreQueryBuilder.toString ()); Iterable <Benote> searchResult = userDao.Search (FunktionenCoreQueryBuilder); Iterator <Bers <Unter> iterator = searchResult.Iterator (); List <Benetzbuchs> list = new ArrayList <Bener> (); while (iterator.hasnext ()) {list.add (iterator.next ()); } Rückgabeliste; }}Hier habe ich einfach verschiedene Methoden geschrieben, die Hauptmethode ist Abfrage. Zu den Abfragen gehören Volltext-Suche, Paginierungsabfrage und Abfrage zur Gewichtsabfrage. Was erklärt werden muss, ist die Gewichtsanfrage. Je höher die Gewichtsbewertung, desto höher ist das Abfrageergebnis. Wenn für andere Daten keine Punktzahl festgelegt ist, beträgt der Standardwert 1. Wenn Sie diese Anweisungen nicht abfragen möchten, verwenden Sie einfach SetMinScore, um sie auf mehr als 1 einzustellen.
Codestests
Rufen Sie die Schnittstelle an, um Daten hinzuzufügen
Neue Daten:
Post http: // localhost: 8086/api/user {"id": 1, "name": "zhang san", "Alter": 20, "Beschreibung": "Zhang san ist ein Java-Entwicklungsingenieur", "Createtm": "2018-4-25 11:07:42} {" id ": 2," name ":" name ":" name ":" name ":" SI ist ein Testingenieur "," CreateTM ":" 1980-2-15 19:01:32 "} {" ID ": 3," Name ":" Wang Wu "," Alter ": 25," Beschreibung ":" Wang Wu ist ein Betrieb und Wartungsingenieur "," Createtm ":" 2016-8-21 06:11:32 "}} Volltexterfrage durchführen
fragen
http: // localhost: 8086/api/user? SearchContent = Ingenieur
zurückkehren
[{"id": 2, "name": "li si", "Alter": 14, "Beschreibung": "Li si ist ein Testingenieur", "Createtm": "1980-2-15 19:01:32"}, {"id": 1, "Name": "Zhang", "Age", "Age": "Beschreibung": "Beschreibung": "": "Zhang," Zhang, "Zhang," Zhang, "Zhang in der Entwicklung", ":": ":" Zhang, "Zhang in der Entwicklung", ":": ":" Zhang, "Zhang in der Entwicklung", ":" ":": "Zhang," Zhang, "java Development", "": "Beschreibung": "": "zhang in Sany": "zhang in der Entwicklung", ":": "zhang in Sany,": ":" zhang san is ":" java entwickelungsingener "2018-4-25 11:07:42"}, {"ID": 3, "Name": "Wang Wu", "Alter": 25, "Beschreibung": "Wang Wu ist ein Betriebs- und Wartungsingenieur", "Createtm": "2016-8-21 06:11:32"}] Führen Sie eine Paginierungsanfrage durch
fragen
http: // localhost: 8086/api/user? pagenumber = 0 & pageSize = 2 & searchContent = Ingenieur
zurückkehren
[{"id": 2, "name": "li si", "Alter": 14, "Beschreibung": "Li si ist ein Testingenieur"}, {"ID": 1, "Name": "Zhang san", "Alter": 20, "Beschreibung": "Zhang San ist ein Java -Entwicklungsingenieur"}]] Gewichtsanfrage durchführen
fragen
http: // localhost: 8086/api/user2? searchContent = li si
zurückkehren
[{"ID": 2, "Name": "Li Si", "Alter": 24, "Beschreibung": "Li Si ist ein Testingenieur", "Createtm": "1980-2-15 19:01:32"}]Die Anweisung des Gewichtsabfragedrucks:
Query Anweisung: {{"function_score": {"Funktionen": [{"filter": {"bool": {"bool": {"sollte": {"match": {"name": {"query": "li si", "type": "boolean"}}},}},}}}}}}}}}}}}}}}}}}}}}}}}}}}}}: 10.00. {"bool": {"sollte": {"Match": {"Beschreibung": {"Query": "li si", "Typ": "boolean"}}}}}}, "Gewicht": 100.0}], min_score ": 2.0}}}}}HINWEIS: Da das Mindestgewicht von SetMinScore in 2 eingestellt ist, werden irrelevante Daten nicht angezeigt. Wenn Sie es anzeigen möchten, entfernen Sie es einfach im Code.
Nach dem Hinzufügen neuer Daten können Sie eingeben: http: // localhost: 9200/_plugin/head/im Browser
Klicken Sie dann auf Basic -Abfrage, um die hinzugefügten Daten anzuzeigen. Wenn Sie eine Anweisungsabfrage verwenden möchten, können Sie die von der Konsole im Programm gedruckte Abfrageanweisung für die Abfrage an die Abfrageschnittstelle einfügen!
Hinweis: Ich habe Elasticsearch hier unter Windows installiert und den ES -Plugin -Kopf installiert. Die spezifischen Installationsschritte befinden sich am Ende des Artikels.
Zusätzlich zu SpringData gibt es tatsächlich andere Methoden zum Betrieb von Elasticsarch.
Verwenden Sie beispielsweise die native Elasticsearch -API und verwenden Sie die Transportclient -Klasse, um sie zu implementieren.
Oder verwenden Sie es, um durch die Frühling einzukapseln, und injizieren Sie einfach die Bohne in die Serviceschicht.
Beispiel:
@Autowired ElasticSearchTemplate ElasticSearchTemplate;
Die oben genannten Methoden haben jedoch ihre Einschränkungen, dh, da die Version von Elasticsearch geändert wird, wird die relevante Java-API jedoch ständig angepasst, dh nachdem die Serverversion von Elasticsearch geändert wurde, muss der Code des Clients möglicherweise erneut geschrieben werden.
Daher führt es ein sehr nützliches Drittanbieter-Tool-Scherz ein. Es verkauft Elasticsearch und füllt die Lücke im Elasticsearch Httprest Interface -Client. Es ist für Elasticsearch 2.x oder über Versionen geeignet, und es müssen aufgrund der Änderung der Elasticsearch -Serverversion den Code nicht ändern!
Scherz
Fügen Sie zunächst die folgenden Abhängigkeiten in Maven hinzu:
<Depopenty> <gruppe> io.searchbox </Groupid> <artifactId> jest </artifactId> <version> 5.3.3 </Version> </abhängig>
Schreiben Sie dann den relevanten Testcode.
Die Kommentare im Code sollten sehr vollständig sein, daher werde ich hier nicht zu viel über den Code sprechen.
Import Java.util.ArrayList; Import java.util.list; import org.elasticsearch.index.query.querybuilders; import org.elasticsearch.search.builder.searchsourcebuilder; import com.pancm.pojo.user; io.searchbox.client.jestclientFactory; import io.searchbox.client.jestresult; importieren io.searchbox.client.config.httpclientconfig; import io.searchbox.core.bulk; import io.search.core.core.bulkresult; io.searchbox.core.documentResult; importieren io.searchbox.core.index; import io.searchbox.core.search; import io.searchbox.indices.createinNex; import io.searchbox.indices.deleteIndex; import io.searchbox.indices.maping.maping.maping.maping.maping.maping.maping.maping.maping.maping.maping.maping.maping.maping.maping.mapping.maping.maping.maping.maping.maping.maping.maping.maping.maping.maping.maping.maping.maping.maping.maping.maping.maping.maping.maping.Mapping. io.searchbox.indices.mapping.putmapping; öffentliche Klasse Jesttest {private static JestClient JestClient; private static String indexname = "userIndex"; // private static String indexname = "userIndex2"; private statische String typename = "user"; private statische String elasticips = "http://192.169.2.98:9200"; // private statische String elasticips = "http://127.0.0.1:9200"; public static void main (String [] args) löst eine Ausnahme aus {jestclient = getJestClient (); InsertBatch (); serach1 (); serach2 (); serach3 (); jestclient.close (); · factory.sethttpclientConfig (neue httpclientConfig.builder (elasticips) .Connimeout (60000) .ReadTimeout (60000) .multitHhread (wahr) .build ()); return factory.getObject (); } public static void InsertBatch () {list <Object> objs = new ArrayList <Object> (); objs.add (neuer Benutzer (1L, "Zhang San", 20, "Zhang San ist ein Java-Entwicklungsingenieur", "2018-4-25 11:07:42")); objs.add (neuer Benutzer (2L, "Li Si", 24, "Li Si ist ein Testingenieur", "1980-2-15 19:01:32"); objs.add (neuer Benutzer (3L, "Wang Wu", 25, "Wang Wu ist Betriebs- und Wartungsingenieur", "2016-8-21 06:11:32")); boolescher Ergebnis = falsch; try {result = InsertBatch (JESTCLIENT, INDEXNAME, TYPENAME, OBJS); } catch (Ausnahme e) {e.printstacktrace (); } System.out.println ("batch neu:"+result); } / *** Volltext -Suche* / public static void Serach1 () {String query = "Ingenieur"; try {SearchSourcebuilder SearchSourCebuilder = new SearchSourcebuilder (); SearchSourcebuilder.Query (querybuilders.queryStringQuery (Abfrage)); // Seite SECKSOURCEBUIMER.FROM (0) .SIZE (2); System.out.println ("Volltext-Suchanweisung Anweisung:"+SearchSourcebuilder.toString ()); System.out.println ("Volltext-Suche retektiert Ergebnis:"+such (jestclient, indexname, TypName, SearchSourcebuilder.toString ())); } catch (Ausnahme e) {e.printstacktrace (); }} / *** exakte Suche* / public static void serach2 () {try {SearchSourCebuilder SearchSourcebuilder = new SearchSourcebuilder (); SearchSourcebuilder.Query (Querybuilders.terMQuery ("Age", 24)); System.out.println ("exakte Suchanweisung Anweisung:"+SearchSourcebuilder.toString ()); System.out.println ("Exakte Suche return Ergebnis:"+such (jestclient, indexname, typename, SearchSourcebuilder.toString ())); } catch (Ausnahme e) {e.printstacktrace (); }} / *** Intervallsuche* / public static void serach3 () {String createTM = "createTM"; String von = "2016-8-21 06:11:32"; String to = "2018-8-21 06:11:32"; try {SearchSourcebuilder SearchSourCebuilder = new SearchSourcebuilder (); SearchSourcebuilder.Query (Querybuilders.RangeQuery (CreateTM) .gte (von) .lte (to)); System.out.println ("Intervallsuchanweisung:"+SearchSourcebuilder.toString ()); System.out.println ("Intervallsuche gibt Ergebnis zurück:"+suche (jestclient, indexname, typename, SearchSourcebuilder.toString ())); } catch (Ausnahme e) {e.printstacktrace (); }} / ** * Index erstellen * @param indexName * @return * @throws Exception * / public boolean createIndex (JESTCLIENT JESTCLIENT, STRING INDEXNAME) löst Ausnahme aus {Jestresult jr = jestclient.execute (New CreateIdex.builder (Index) .build ()); return jr.ISSUCSEPEEDED (); } / ** * Neue Daten * @param indexname * @param typename * @param source * @return * @throws Exception * / public boolean Insert (JESTCLIENT JESTCLIENT, STRING INDEXNAME, STRING TYPENAME, SINGSELLEMS) löst eine Ausnahme aus {putmapping putmapping = new putmapping.builder (Indexname, TypName, TypName, TypName). Jestresult jr = jestclient.execute (putmapping); return jr.ISSUCSEPEEDED (); } / ** * Abfragedaten * @param indexName * @param typename * @return * @throws Exception * / public static String getIndexmaping (JestClient jestClient, String IndexName, String typeName) löscht Ausnahme {getMapping getMapping = new Getmaping.builder (). Jestresult jr = jestclient.execute (getMapping); return jr.getJonstring (); } / ** * Daten in Stapel hinzufügen * @param indexname * @param typename * @param objs * @return * @throws Exception * / public static boolean InsertBatch (JestClient Jestclient, String Index, String typeName, List <Dojore> objs) löst Ausnahme {bulk.builder bulk = newn. Bulk.builder (). DefaultIndex (Indexname) .DefaultType (typename); für (Objekt obj: objs) {index index = neuer index.builder (obj) .build (); Bulk.Addaction (Index); } Bulkresult br = jestclient.execute (bulk.build ()); return br. issucresed (); } / ** * Volltextsuche * @param indexName * @param typename * @param query * @return * @throws Exception * / public static String Search (JESTCLIENT JESTCLIENT, STRING INDEXNAME, STRING TYPEName, String Query) Throws Exception {Search Search.builder (Query). Jestresult jr = jestclient.execute (Suche); // system.out.println ("-"+jr.getJonstring ()); // system.out.println ("-"+jr.getSourceasObject (user.class)); return jr.getSourceAsString (); } / ** * Index löschen * @param indexName * @return * @throws Exception * / public boolean delete (jestClient jestClient, String IndexName) löst Ausnahme aus {jestresult jr = jestclient.execute (new DeleteIndex.builder (Index) .build ()); return jr.ISSUCSEPEEDED (); } / ** * Daten löschen * @param indexName * @param typename * @param id * @return * @throws Exception * / public boolean delete (jestClient jestClient, String indexName, String typeName, String -ID) löst Ausnahme aus {documentresult dr = jestclient.execute (New (New Delete.builder (id) .Index (indexname) .type (typeName) .build ()); Return Dr.ISSUCSEPEEDED (); }Hinweis: Erklären wir vor dem Testen zunächst, dass die auf dem lokale Windows -System installierte Elasticsearch -Version 2.3.5 und die auf dem Linux -Server installierte Elasticsearch -Version 6.2 beträgt.
Testergebnisse
Volltext -Suche
Volltext-Suchanweisung Anweisung: {"aus": 0, "Größe": 2, "Query": {"query_string": {"query": "Ingenieur"}}} Volltext-Suche zurückgegeben: {"id": 1, Name " Ingenieur "," CreateTM ":" 2018-4-25 11:07:42 "}, {" ID ": 2," Name ":" Li Si "," Alter ": 24," Beschreibung ":" Li si ist ein Testingenieur "," Createtm ":" 1980-2-15 19:01:32 "}"}Übereinstimmung der Suche
Genauige Suchanweisung Anweisung: {"Query": {"Begriff": {"Alter": 24}}} genaue Suche Rücksuche Ergebnis: {"ID": 2, "Name": "Li Si", "Age": 24, "Beschreibung": "Li Si ist ein Testingenieur", "Createtm": "1980-2-15 19:01:32"} "}Zeitintervallsuche
Interval search statement:{ "query" : { "range" : { "createtm" : { "from" : "2016-8-21 06:11:32", "to" : "2018-8-21 06:11:32", "include_lower" : true, "include_upper" : true } } }} interval search returns result: {"id":1,"name":"Zhang San "," Alter ": 20," Beschreibung ":" Zhang San ist ein Java-Entwicklungsingenieur "," Createtm ":" 2018-4-25 11:07:42 "}Nach dem Hinzufügen neuer Daten können wir zu Linux Kibana gehen, um verwandte Abfragen durchzuführen, und die Abfrageergebnisse sind wie folgt:
Hinweis: Kibana ist eine Open -Source -Software in Elch. Kibana bietet logarithmische Analyse-freundliche Web-Schnittstellen für Logstash und Elasticsearch, um wichtige Datenprotokolle zusammenzufassen, zu analysieren und zu durchsuchen.
Die durch den Test im obigen Code zurückgegebenen Ergebnisse stimmen mit unseren Erwartungen überein. Unter ihnen wird nur ein kleiner Teil von Jestclient verwendet. Für mehr Verwendung können Sie die offizielle Dokumentation von Jestclient überprüfen.
Installieren Sie Elasticsearch unter Windows
1. Dokumentvorbereitung
Download -Adresse: https://www.elastic.co/downloads
Wählen Sie die mit Elasticsearch verwandte Version aus, wählen Sie die Suffix -Name -ZIP -Datei zum Herunterladen aus und entpacken Sie sie nach dem Herunterladen.
2. Starten Sie Elasticsearch
Gehen Sie zum Bin -Verzeichnis und führen Sie elasticsearch.bat aus
Dann geben Sie ein: localhost: 9200 auf dem Stöbern
Das erfolgreiche Anzeigen der Schnittstelle bedeutet Erfolg!
3. Installieren Sie das ES-Plug-In
Webverwaltungsschnittstelle Kopfinstallation
Geben Sie das Bin -Verzeichnis ein, öffnen Sie CMD und geben Sie die DOS -Schnittstelle ein
Eingeben: plugin install mobz/elasticsearch-head
Machen Sie einen Download
Geben Sie nach erfolgreichem Download ein: http: // localhost: 9200/_plugin/head/
Wenn die Schnittstelle angezeigt wird, ist die Installation erfolgreich!
4. Registrieren Sie Service
Geben Sie das Bin -Verzeichnis ein, öffnen Sie CMD und geben Sie die DOS -Schnittstelle ein
Eingeben:
service.bat installService.bat start
Nach Erfolg eintreten
services.msc
Springen Sie zur Service -Service -Schnittstelle, um den laufenden Status von ES direkt anzuzeigen!
andere
Elasticsearch Official Website API -Adresse:
https://www.elastic.co/guide/en/elasticsearch/client/java-api/2.3/index.html
JESTCLIENTGITHUB -Adresse:
https://github.com/searchbox-io/jest (lokaler Download)
Ich habe das Projekt auf GitHub gestellt.
https://github.com/xuwujing/springboot (lokaler Download)
Zusammenfassen
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Referenzwert für das Studium oder die Arbeit eines jeden hat. Wenn Sie Fragen haben, können Sie eine Nachricht zur Kommunikation überlassen. Vielen Dank für Ihre Unterstützung bei Wulin.com.