Dieser Artikel beinhaltet nicht die spezifischen Prinzipien von Elasticsearch, sondern zeichnet nur auf, wie Daten schnell in MySQL für die Volltext-Suche importiert werden können.
Bei der Arbeit müssen Sie eine Suchfunktion implementieren und vorhandene Datenbankdaten importieren. Der Teamleiter empfiehlt, Elasticsearch zur Implementierung zu verwenden. Sie können Tutorials online durchsuchen, bei denen es sich um relativ alte Artikel handelt. Ich habe keine andere Wahl, als es selbst zu erkunden. Beziehen Sie sich in der Dokumentation der ES und erstellen Sie schließlich den Service. Ich werde es aufzeichnen. Ich hoffe, dass Freunde mit den gleichen Bedürfnissen Umwege vermeiden und nach diesem Tutorial schnell einen verfügbaren Elasticsearch -Service erstellen können.
Es Konstruktion
ES -Builds können direkt Zip -Dateien und Docker -Container herunterladen. Relativ gesehen ist Docker für uns besser geeignet, ES -Dienste auszuführen. Es ist möglich, einfach einen Cluster zu erstellen oder eine Testumgebung zu erstellen. Die Containermethode wird auch hier verwendet. Erstens brauchen wir eine Dockerfile:
Von docer.elastic.co/elasticsearch/elasticsearch-osse:6.0.0# Sendenkonfiguration enthält die New Elasticsearch.yml und Keystore.jks Dateien Copy --Chown = Elasticsearch: ElasticSearch Conf//usr/shareSearch/Elasticsarch/Konfiguration/# Ikrun. https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.0.0/elasticsearch-analysis-ik-6.0.zip# Installieren Sie Readonlyrestrun ./bin/elasticsearch-plugin Installation https://github.com/hyy-yu/beziercurvedemo/raw/master/readonryrest-16.14_es6.0.zipuser elasticsearchcmd ./bin/elasticsarch
Hier ist eine Erklärung der obigen Operation:
Elictic Configuration Elasticsearch.yml
cluster.name: "docker-cluster" network.host: 0.0.0.0# minimum_master_nodes muss explizit eingestellt werden, wenn sie auf einem öffentlichen IP# gesetzt werden, um einzelne Knotencluster zu ermöglichen. auf es bootstrap.memory_lock: true http.type: SSL_NETTY4READONRYREST: Enable: TRUE SSL: ENABLE: TRUE KEYSTORE_FILE: "Server.jks" Keystore_Pass: Server Key_Pass: Server -Zugriff: - Name: "Block 1 - Root" -Styp "-Styp:" ["Benutzer"] Indizes: ["Papier*"] Aktionen: ["Indizes: Daten/Read/*"] Benutzer: - Benutzername: root auth_key_sha256: cb7c98bae153065db931980a13bd45ee3a77cb8f27a7dfee680A: [userNee680Mfe680Mf68107777777777777777777777777777777777777777777. Xiaoming Auth_key: Xiaoming: Xiaoming -Gruppen: ["Benutzer"]
Hier Bootstrap.Memory_lock: True ist eine Grube, die den Speicheraustausch verbietet. Das Dokument hat bereits erklärt, dass einige Betriebssysteme während der Laufzeit vorübergehend nicht genutzt auf einen Bereich der Festplatte tauschen werden. Dieses Verhalten wird jedoch die Ressourcenauslastungsrate von ES steigen und sogar das System nicht reagieren.
In der Konfigurationsdatei ist bereits offensichtlich, dass ein Root -Benutzer zur Administratorgruppe gehört, und Admin hat alle Berechtigungen. Da sich Xiaoming in der Benutzergruppe befindet, kann er nur auf den Papierindex zugreifen und nur lesen, aber nicht funktionieren. Eine detailliertere Konfiguration finden Sie unter: Readonryrest -Dokumentation
Zu diesem Zeitpunkt wurden die Vorbereitungen für ES abgeschlossen. Docker Build -t Essimage: Tag. Docker Run -P 9200: 9200 Essimage: Tag Run.
Wenn https://127.0.0.1:9200/ zurückgibt
{"Name": "Vakwrir", "cluster_name": "Docker-Cluster", "cluster_uuid": "ysydowkvrh2swz907S2M_W", "Version": {"Nummer": "6.0.0," Build_hash ":" 8f0685b "," Build_date ": "2017-11-10t18: 41: 22.859z", "Build_snapshot": Falsch, "Lucene_Version": "7.0.1", "minimum_wire_compatibility_version": "5.6.0", "minimum_index_compatibilibility_version": "5.0.0.0.0"}, "},"}, "Darm", "Der Protagonist unseres Tutorials ist erschienen. Ich werde mehrere häufig verwendete APIs teilen, um es zu necken und zu debuggen:
{{url}} wird durch Ihre lokale ES -Adresse ersetzt.
MySQL -Daten importieren
Ich verwende hier MySQL -Daten, aber tatsächlich sind andere Datenbanken gleich. Der Schlüssel ist, wie man importiert. Das Online-Tutorial empfiehlt das MySQL-Plug-In für Logstash, Beat und ES für den Import. Ich habe es auch versucht. Die Konfiguration ist umständlich und die Dokumente sind spärlich. Wenn die Datenbankstruktur etwas kompliziert ist, ist das Import eine mühsame Aufgabe, daher wird sie nicht empfohlen. Tatsächlich hat ES in jeder Sprache entsprechende API -Bibliotheken. Sie können die Daten auf Sprachebene in JSON zusammenstellen und sie über die API -Bibliothek an ES senden. Der Prozess ist ungefähr wie folgt:
Ich benutze Golangs ES -Bibliothek elastisch. Sie können nach GitHub nach anderen Sprachen suchen, und die Betriebsmethode ist gleich.
Verwenden Sie als Nächstes eine einfache Datenbank, um sie vorzustellen:
Papiertisch
| Ausweis | Name |
|---|---|
| 1 | Peking Nr. 1 Grundschule Simulation |
| 2 | Jiangxi Peking General College -Aufnahmeprüfungsfragen |
Provinztisch
| Ausweis | Name |
|---|---|
| 1 | Peking |
| 2 | Jiangxi |
Paper_province table
| paper_id | Provinz |
|---|---|
| 1 | 1 |
| 2 | 1 |
| 2 | 2 |
Wie oben erwähnt, sind Papier und Provinz viele zu viele Beziehungen. Jetzt, da Papierdaten in ES eingegeben werden, können Sie nach dem Papiernamen Fuzzyly suchen oder durch die Provinz filtern. Das JSON -Datenformat lautet wie folgt:
{"ID": 1, "Name": "Peking Nr. 1 Grundschule Simulationsvolumen", "Provinzen": [{"ID": 1, "Name": "Peking"}]} Erstellen Sie zunächst eine maping.json -Datei, die die Speicherstrukturdefinition von Daten in ES ist.
{ "mappings":{ "docs":{ "include_in_all": false, "properties":{ "id":{ "type":"long" }, "name":{ "type":"text", "analyzer":"ik_max_word" // Use the largest word parterator}, "provinces":{ "type":"nested", "properties":{ "ID": {"Typ": "Integer"}, "Name": {"Typ": "Text", "Index": "False" // nicht indiziert}}}}}}}}}}}}, "Einstellungen": {"number_of_shards": 1, "number_of_replicas": "number_of_replicas": 0}} ":" number_of_replicas ": 0}} $": "number_of_replicas": 0}}}}}}}}}} $ ":" number_of_roplicas ":" number_of_replicas ": 0}}}}}}}}}}}}}}}}}}}}}}}}:Es ist zu beachten, dass das Feld _All abgesagt ist. Mit diesem Standard werden alle Speicherfelder gesammelt, um eine bedingungslose Suche nach eingeschränkter Suche zu erzielen. Der Nachteil ist, dass der Raum viel einnimmt.
Ich habe die Shard -Nummer auf 1 gesetzt, und es sind keine Repliken festgelegt. Immerhin ist dies kein Cluster und die verarbeiteten Daten sind nicht viel. Wenn eine große Menge an Daten verarbeitet werden muss, können Sie die Anzahl der Scherben und Repliken selbst festlegen.
Zunächst hat CA.CRT eine Verbindung zu ES hergestellt, die mit der Selbstsignatur von JKs zusammenhängt. Natürlich verwende ich hier InSecureskipverify, um die Überprüfung der Zertifikatdatei zu ignorieren.
func initelasticsearch () {pool: = x509.Newcertpool () crt, err0: = ioutil.readFile ("conf/ca.crt") if err0! & tls.config {rootCas: Pool, InSecureskipverify: true},} httpclient: = & http.client {transport: tr} // Hintergrund konstruieren elasticclient var erraste elasticclient elastic.setgzip (true), elastic.sethttpclient (httpclient), elastic.setsniff (false), // Cluster -Sniff, denken Sie daran, einen einzelnen Knoten zu schließen. "Search_client_error") return} // Elasticclient Construction ist abgeschlossen // Abfragen Sie, ob ein Papierindex existiert. gesendet, wenn existieren {if! isIndexintegrity (elasticclient) {// den aktuellen Index löschen und sich auf den Wiederaufbau von Deletersponse vorbereiten, err: = elasticclient.deleteIndex (myconfig.elasticIndexname) .do (context.background ()) if ERR! = nil || ! DeleterePonse.acknowgedged {kann nichtOpenes (err, "delete_index_error") return}} else {return}} // Hintergrund -Abfrage -Datenbank und Senden Sie Daten an elasticsearch go fetchDbGetAnpaperandsendToes ()} Typ paperSearch struct {paperId int64 `gorm:" primary_key; spalte: f_paper_id; type: bigint (20) "json:" id "` name string `gorm:" spalte: f_name; Größe: 80 "json:" name "` provinces [] province `gorm:" viele2Many: t_paper_province ". JSON: "Provinces" `// Provinzen, für die das Testpapier anwendbar ist} func fetchDbGetAlppaperandSendToes () {// Papier var Allpaper [] Papiere Search getdb (). Tabelle (" t_papers "). Getdb (). Table ("t_provinzen"). Schließt sich ("innere join` t_paper_province` on `t_paper_province`.`province_f_province_id` =` t_provinces`.`f_province_id`) .where (t_paper_paper.provinc. Allpaper [i] .paperId) .find (& allPro) AllPaper [i] .Provinces = AllPro} if len (AllPaper)> 0 {// an es - create Index createService: = getElasticsearch (). CreateIndex (myconfig.elasticIndexname) // Index_defaultding. createService.body (index_default_seting) createuresult, err: = createService.do (context.background ()) Wenn er! // - Senden Sie alle Papierbulkrequest: = GetElasticsearch (). Bulk () für i: = Bereich Allpaper {indexReq: = elastic.newbulKindexRequest (). Doc (Allpaper [i]) bulkrequest.add (indexReq)} // do sendet die Bulk -Anfragen an Elasticsearch BulkResponse, ERR: = Bulkrequest.do (context.background ()) Wenn er! ! Verwenden Sie nach dem Durchlaufen des obigen Codes {{url}}/_ cat/Indices? V, um festzustellen, ob der neu erstellte Index in ES angezeigt wird, und verwenden Sie {{url}}/papers/_Search, um zu sehen, wie viele Dokumente getroffen werden. Wenn die Anzahl der Dokumente der in der Vergangenheit gesendeten Datenmenge entspricht, wird der Suchdienst in Betracht gezogen.
suchen
Sie können nun nach Provinz- und Q nach Testpapieren suchen, und der Standard wird nach Relevanz -Score sortiert.
// q Such String ProvinceId Limited Province ID ID Limit Pagination Parameter Func Sacepaper (q String, ProvinceId Uint, Limit int, Seite int) (Liste [] Papiere, TotalPage int, aktuelle Page int, pageiSend int, returnRerr eRROR) {// Wenn die Bedingungen nicht getroffen werden, verwenden Sie die Datenbank, um zu suchen. courseId, gradeId, provinceId, paperTypeId, limit, page) } list = make([]PaperSimple, 0) totalPage = 0 currentPage = page pageIsEnd = 0 returnErr = nil client := GetElasticSearch() if client == nil { return SearchPaperLocal(q, courseId, gradeId, provinceId, paperTypeId, limit, page) } // There is a problem with ElasticSearch, use the Datenbank zu suchen, wenn! isIndexintegrity (client) {return secaperLocal (q, curseId, gradeId, provinceId, paperTypeId, limit, page)} if! client.isrunning () {client.start ()} defer client elastic.newmatchQuery ("Name", q) // Provinz IF PROVINCID> 0 && ProvincID! boolQuery.must (pronest)} boolquery.must (matchQuery) für _, e: = Bereich TermQuerys {boolQuery.must (e)} highlight: = elastic.newhighlight () highlight.field (elastic_search_field_field_name) highlight.pretags. highlight.postTags (elastic_search_search_field_tag_end) searchResult, err2: = client.search (myconfig.elasticIndexname). Highlight (Highligt). Abfrage (Boolquery). Von ((Seite - 1) * Grenze). Größe (Grenze). Do (context.background ()) Wenn er2! SearchResult.hits.hits {var p paperSearch err: = json.unmarshal (*hit.source, & p) if err! len(hit.Highlight[ELASTIC_SEARCH_SEARCH_FIELD_NAME]) > 0 { p.Name = hit.Highlight[ELASTIC_SEARCH_SEARCH_FIELD_NAME][0] } list = append(list, p) } count := searchResult.TotalHits() currentPage = page if count > 0 { totalPage = int(math.Ceil(float64(count) / float64 (limit)))} if curralPage> = TotalPage {pageisend = 1}} else {// no Hits}} return}Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.