Artikel ini tidak melibatkan prinsip-prinsip spesifik Elasticsearch, tetapi hanya mencatat cara mengimpor data dengan cepat di MySQL untuk pencarian teks lengkap.
Di tempat kerja, Anda perlu menerapkan fungsi pencarian dan mengimpor data basis data yang ada. Pemimpin tim merekomendasikan penggunaan Elasticsearch untuk mengimplementasikannya. Anda dapat mencari melalui tutorial online, yang merupakan artikel yang relatif lama. Saya tidak punya pilihan selain menjelajahinya sendiri. Lihat dokumentasi ES dan akhirnya membangun layanan. Saya akan merekamnya. Saya berharap bahwa teman -teman dengan kebutuhan yang sama dapat menghindari jalan memutar dan dapat dengan cepat membangun layanan Elasticsearch yang tersedia sesuai dengan tutorial ini.
Konstruksi ES
ES Build dapat langsung mengunduh file zip dan wadah Docker. Secara relatif, Docker lebih cocok bagi kami untuk menjalankan layanan ES. Dimungkinkan untuk dengan mudah membangun cluster atau membuat lingkungan pengujian. Metode wadah juga digunakan di sini. Pertama, kita membutuhkan dockerfile:
Dari docker.elastic.co/elasticsearch/elasticsearch-oss:6.0.0# Konfigurasi Kirim Termasuk Konfigurasi Elasticsearch.yml dan KeyStore.jks File Salin --chown = Elasticsearch: Elasticsearch Conf//USR/Share/Elasticsearch/Config/# Install Ikrun. https://github.com/medcl/elasticsearch-analys-ik/releases/download/v6.0.0/elasticsearch-analysis-ik-6.0.0.zip# Install readonlyRestrun ./bin/elasticsearch-plugin install https://github.com/hyy-yu/beziercurvedemo/raw/master/readonlyrest-1.16.14_es6.0.0.zipuser Elasticsearchcmd ./bin/elasticsearch
Berikut adalah penjelasan tentang operasi di atas:
Elictic Configuration Elasticsearch.yml
cluster.name: "Docker-cluster" network.host: 0.0.0.0# minimum_master_nodes perlu diatur secara eksplisit ketika terikat pada IP publik# diatur ke 1 untuk memungkinkan cluster simpul tunggal# detail: https://github.com/elastic.nodesearch/pull/1728888888888888888888888888888 bootstrap.memory_lock: true http.type: ssl_netty4readonlyrest: aktifkan: true ssl: aktifkan: true keystore_file: "server.jks" KEYSTORE_PASS: Server KEY_PASS: Server Access_control_rules: - Nama: "Blok 1 - Root" Tipe: Server: Server Access_Control_rules: - Nama: "Blok 1 - ROOT" TYPE: "Server Access_control_rules: - Nama:" Blok 1 - Root " ["Pengguna"] Indeks: ["Kertas*"] Tindakan: ["Indeks: Data/Baca/*"] Pengguna: - Nama pengguna: root auth_key_sha256: cb7c98bae153065db931980a13bd4577777cb8f27a7a7dfee682: "" - "" -dombe137777777 xiaoming auth_key: xiaoming: grup xiaoming: ["user"]
Di sini bootstrap.memory_lock: true adalah lubang, melarang pertukaran memori. Dokumen tersebut telah menjelaskan bahwa beberapa OS akan menukar memori sementara yang tidak digunakan ke area hard disk selama runtime. Namun, perilaku ini akan melambung tingkat pemanfaatan sumber daya ES, dan bahkan membuat sistem tidak dapat merespons.
Sudah jelas dalam file konfigurasi bahwa pengguna root milik grup admin, dan admin memiliki semua izin. Karena Xiaoming ada di grup pengguna, ia hanya dapat mengakses indeks kertas, dan hanya dapat membaca, tetapi tidak dapat beroperasi. Untuk konfigurasi lebih rinci, silakan lihat: Dokumentasi ReadOnlyRest
Pada titik ini, persiapan untuk ES telah selesai. Docker Build -t Esimage: Tag. Docker Run -P 9200: 9200 ESIMAGE: TAG RUN.
Jika https://127.0.0.1:9200/ kembali
{"name": "vakwir", "cluster_name": "docker-cluster", "cluster_uuid": "ysydowkvrh2swz907s2m_w", "versi": {"nomor": "6.0.0", "Build_Hash": "8f0685B", "", "", "8F0685B", "". "2017-11-10T18: 41: 22.859z", "build_snapshot": false, "lucene_version": "7.0.1", "minimum_wire_compatibility_version": "5.6.0", "minimum_index_compatibility_versiony"}}, "},"}, "},"}, "},"}, "},"}, "},"}, "},"}, "},"}, "},"}, "},"}, "},"Protagonis tutorial kami telah muncul. Saya akan membagikan beberapa API yang umum digunakan untuk menggoda dan men -debug:
{{url}} diganti dengan alamat ES lokal Anda.
Impor data MySQL
Saya menggunakan data MySQL di sini, tetapi pada kenyataannya, database lain adalah sama. Kuncinya adalah cara mengimpor. Tutorial online akan merekomendasikan plug-in MySQL untuk logstash, beat, dan ES untuk impor. Saya juga sudah mencobanya. Konfigurasinya rumit dan dokumennya jarang. Jika struktur basis data sedikit rumit, impor adalah tugas yang melelahkan, jadi tidak disarankan. Faktanya, ES memiliki perpustakaan API yang sesuai di setiap bahasa. Anda dapat mengumpulkan data ke JSON di tingkat bahasa dan mengirimkannya ke ES melalui perpustakaan API. Prosesnya kira -kira sebagai berikut:
Saya menggunakan perpustakaan ES Golang elastis. Anda dapat mencari di GitHub untuk bahasa lain, dan metode pengoperasiannya sama.
Selanjutnya, gunakan database sederhana untuk memperkenalkannya:
Meja kertas
| pengenal | nama |
|---|---|
| 1 | Beijing Simulasi Sekolah Dasar No. 1 |
| 2 | Jiangxi Beijing General College Pintu Masuk Pertanyaan |
Tabel Provinsi
| pengenal | nama |
|---|---|
| 1 | Beijing |
| 2 | Jiangxi |
Tabel kertas_province
| kertas_id | province_id |
|---|---|
| 1 | 1 |
| 2 | 1 |
| 2 | 2 |
Seperti disebutkan di atas, kertas dan provinsi adalah banyak hubungan. Sekarang data kertas dimasukkan ke dalam ES, Anda dapat mencari secara tidak jelas dengan nama kertas, atau menyaring provinsi. Format data JSON adalah sebagai berikut:
{"id": 1, "name": "Beijing No. 1 Volume Simulasi Sekolah Dasar", "Provinsi": [{"id": 1, "Name": "Beijing"}]} Pertama siapkan file pemetaan.json, yang merupakan definisi struktur penyimpanan data dalam ES.
{"Mappings": {"docs": {"include_in_all": false, "properties": {"id": {"type": "long"}, "name": {"type": "text", "analyzer": "IK_MAX_WORD" // Gunakan kata kata terbesar}, "{" {{"{" {"{" IK_MAX: " "id": {"type": "integer"}, "name": {"type": "text", "index": "false" // tidak diindeks}}}}}}}}}}}}, "pengaturan": {"number_ofshards": 1, "number_replicas": {"number_shards": 1, "number_replicas": {"number_shardPerlu dicatat bahwa bidang _all dibatalkan. _All default ini akan mengumpulkan semua bidang penyimpanan untuk mencapai pencarian terbatas tanpa syarat. Kerugiannya adalah bahwa ruang sangat menempati.
Saya mengatur nomor Shard ke 1, dan tidak ada replika yang ditetapkan. Bagaimanapun, ini bukan cluster dan data yang diproses tidak banyak. Jika ada sejumlah besar data yang perlu diproses, Anda dapat mengatur jumlah pecahan dan replika sendiri.
Pertama, buat koneksi dengan ES, CA.CRT terkait dengan tanda tangan diri JKS. Tentu saja, di sini saya menggunakan Insecureskipverify untuk mengabaikan verifikasi file sertifikat.
func initelasticsearch () {pool: = x509.newcertpool () crt, err0: = ioutil.readfile ("conf/ca.crt") jika err0! = nil {cantopenes (err0, "baca crt err") return} pool.AppendCertSfrompem (crt: crt: = hyrspor {{{crt: crt: crt. & tls.config {rootcas: pool, intercureskipverify: true},} httpclient: = & http.client {transport: tr} // latar belakang elasticclient var error kesalahan elastis, erastik. elastic.setgzip (true), elastic.sethttpClient (httpclient), elastic.setsniff (false), // cluster sniff, ingat untuk menutup satu node. CANTEPENES (err, "search_client_error") return} // elasticclient Construction diselesaikan // query apakah ada indeks kertas yang ada, err: = elasticclient.indexexists (myconfig.elasticIndexname) .do (context.background ()) jika err! = nil {canToPenes (erring, "exthing_paper_paper () jika err! Periksa, tidak ada data yang dikirim jika ada {if! isIndexIntegrity (elasticClient) {// hapus indeks saat ini dan bersiaplah untuk membangun kembali deleteresponse, err: = elasticclient.deleteIndex (myconfig.elasticIndexName) .do (context.background ()) if err! = nil || ! deleteresponse.acknowedged {cantopenes (err, "delete_index_error") return}} else {return}} // latar belakang basis data dan kirim data ke elasticsearch go fetchdbgetallpaperandsendtoes ()} Type Papersearch struct {paperId int64 `gorm:" primer_key; kolom: f_paper_id; type: bigint (20) "json:" id "` nama string `gorm:" kolom: f_name; ukuran: 80 "json:" name "` provinsi [] provinsi `gorm:" many2many: t_paper: t_paper_papov; " json: "provinsi" `// provinsi yang makalah uji berlaku} funct fetchdbgetAllpaperandsendtoes () {// fetch paper var allpaper [] papersearch getDb (). Tabel (" t_papers "). Find (& allpaper) // Provinsi untuk i: = range allpaper {var allpro"). GetDb (). Table ("t_provinces"). Bergabung ("BAGIAN INNER` t_paper_province` di `t_paper_province`.`province_f_province_id` =` t_provinces`.`f_province_id`) .where ("t_papince.provinces`. allpaper [i] .paperId) .find (& allpro) allpaper [i] .provinces = allPro} if len (allpaper)> 0 {// kirim ke es - buat indeks createService: = getelasticsearch (). createIndex (myconfig.elasticIndexname) // index_default (). createservice.body (index_default_setting) createresult, err: = createService.do (context.background ()) jika err! = nil {canToPenes (err, "create_paper_index")} if! creatreesult (createxerpaper (createxnaper (creatrexnapex. Semua BulkRequest Paper: = Getelasticsearch (). Bulk () untuk i: = Range Allpaper {IndexREQ: = ELASTIK.NEWBULKINDEXREQUES BulkRequest.Add (IndexReq)} // Do Kirim Permintaan Bulk ke Elasticsearch BulkResponse, err: = bulkRequest.do (context.background ()) jika err! = nil {canToPenes (err, "insert_docs_error") return} // aksi bulk (erron, "inert_docs_error")} // aksi bulk (erron, "leen iferpape (BULKRORT") {cantopenes (err, "insert_docs_nums_error") return} // kirim sukses}} Setelah menjalankan kode di atas, gunakan {{url}}/_ Cat/Indices? V untuk melihat apakah indeks yang baru dibuat muncul di ES, dan gunakan {{url}}/papers/_search untuk melihat berapa banyak dokumen yang terkena. Jika jumlah dokumen sama dengan jumlah data yang Anda kirim di masa lalu, layanan pencarian akan dianggap berjalan.
mencari
Anda sekarang dapat mencari kertas tes oleh Provinceid dan Q, dan standarnya diurutkan berdasarkan skor relevansi.
//q Search string provinceID Limited province id limit page pagination parameters func SearchPaper(q string, provinceId uint, limit int, page int) (list []PaperSearch, totalPage int, currentPage int, pageIsEnd int, returnErr error) { //If the conditions are not met, use the database to search if !CanUseElasticSearch && !MyConfig.UseElasticSearch { return SearchPaperLocal(q, 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 Database untuk mencari jika! isIndexIntegrity (klien) {return searchpaperlocal (q, courseid, gradeid, provinceId, papertypeid, limit, page)} if! client.isrunning () {client.start ()} tunda client.stop () q = html.esceryceying (q) boolquery. elastic.NewMatchQuery("name", q) // Province if provinceId > 0 && provinceId != DEFAULT_PROVINCE_ALL { proBool := elastic.NewBoolQuery() tpro := elastic.NewTermQuery("provinces.id", provinceId) proNest := elastic.NewNestedQuery("provinces", proBool.Must(tpro)) BoolQuery.must (pronest)} boolQuery.must (MatchQuery) untuk _, e: = range termquerys {boolQuery.must (e)} sorotan: = elastic.newhighlight () sorotan (elastic_search_tfield_name) sorotan (ElastigLight (elastic_search_search_field_name) (ELASTASTICED_SECEARCED_NAME) (ELASTASTICECARD_SECEARCHED_NAME) (ELASTASTICECARD_SECEARFField_name) (ELASTASTICECARED_SECEARFField_name) (ELASTASTICECARED_SECEARFField. Sorote.posttags (elastic_search_search_field_tag_end) SearchResult, err2: = client.search (myconfig.elasticIndexName). Sorot (HighLigt). Kueri (boolquery). Dari ((halaman - 1) * batas). Ukuran (batas). Do (context.background ()) jika err2! = Nil {// menangani kesalahan getLogger (). LOGERR ("Terjadi kesalahan saat mencari"+err2.error (), "search_error") // menangani kesalahan returnerr = errors.new ("kesalahan terjadi selama pencarian")} else {if seal se exeRresul.hits.totalhits. searchResult.hits.hits {var p papersearch err: = json.unmarshal (*hit.source, & p) jika err! = nil {// deserialization gagal getLogger (). LOGERR ("kesalahan terjadi selama pencarian"+error (), "search_deserialization_ror") returnerr = error (), "search_deserialization_error") returnerr = "error ()," search_deserialization ") retrorerr =" error (), "search_deserialization") returnerror ("error ()" lift_deserialisasi_error ") returnerr =" error (), "looking_deserialization") retrorerr () len (hit.highlight [elastic_search_search_field_name])> 0 {p.name = hit.highlight [elastic_search_search_field_name] [0]} list = append (daftar, p)} hit float64 (limit)))} jika currentpage> = totalpage {pageisend = 1}} else {// tidak ada hit}} return}Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.