Kata pengantar
Dalam artikel sebelumnya, Springboot, Mybatis, Druid dan PageHelper diintegrasikan dan operasi beberapa sumber data diimplementasikan. Artikel ini terutama memperkenalkan dan menggunakan elastisearch, mesin pencari paling populer, dan menggunakannya dalam kombinasi dengan springboot.
Pengantar Elasticsearch
Elasticsearch adalah server pencarian berdasarkan Lucene. Ini sebenarnya merangkum Lucene dan menyediakan antarmuka operasi API REST. Elasticsearch adalah mesin pencarian dan analisis teks lengkap open source yang sangat terukur yang dapat digunakan untuk dengan cepat menyimpan, mencari dan menganalisis data besar.
Fitur utama Elasticsearch: Terdistribusi, ketersediaan tinggi, penulisan asinkron, multi-API, berorientasi dokumen.
Elasticsearch Core Concepts: Near Real-Time, Cluster, Node (Simpan Data), Indeks, Shard (Slicing Index Shards), Replicas (Slicing dapat mengatur beberapa replika). Ini dapat dengan cepat menyimpan, mencari dan menganalisis sejumlah besar data.
Kasus Penggunaan Elasticsearch: Wikipedia, Stack Overflow, GitHub, dll.
Springboot mengintegrasikan Elasticsearch
Sebelum menggunakan Springboot untuk mengintegrasikan Elasticsearch, kita harus memahami hubungan di antara mereka.
| Versi boot musim semi (x) | Spring Data Elasticsearch Version (Y) | Versi Elasticsearch (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 ** |
Versi springboot yang kami gunakan di sini adalah 1.5.9, dan versi Elasticsearch adalah 2.3.5.
Menggunakan Springboot untuk mengintegrasikan Elasticsearch, umumnya dienkapsulasi menggunakan SpringData, dan kemudian antarmuka lapisan DAO mewarisi kelas ElasticsearchRepository. Kelas ini mengimplementasikan banyak metode, seperti metode CRUD yang umum digunakan.
Penggunaan SpringData
Pertama, buat persiapan yang relevan sebelum digunakan.
Konfigurasi Maven adalah sebagai berikut:
<dependency> <GroupId> org.springframework.boot </groupid> <ArtifactId> Spring-boot-starter-web </stifactid> <version> 1.5.9.release </version> </dependency> <RoupAcid> org.springframework. <version> 1.5.9.release </version> </dependency>
Konfigurasi application.properties
spring.data.elasticsearch.repositories.enabled = truespring.data.elasticsearch.cluster-nodes = 127.0.0.1/: 9300
Catatan: 9300 adalah port dari klien Java. 9200 adalah antarmuka yang mendukung HTTP REST.
Lebih banyak konfigurasi:
spring.data.elasticsearch.cluster-name elasticsearch nama cluster. (Default: Elasticsearch)
spring.data.elasticsearch.cluster-nodes Daftar alamat node cluster, dipisahkan oleh koma. Jika tidak ditentukan, mulailah simpul klien.
spring.data.elasticsearch.propertie digunakan untuk mengonfigurasi properti tambahan klien.
spring.data.elasticsearch.repositories.Enabled mengaktifkan repositori Elasticsearch. (Default: true.)
Menulis kode
Kelas Entitas
@Document (indexName = "userIndex", type = "user") Public Class Pengguna mengimplementasikan serializable { / ** * * / private static final long serialVersionuid = 1l; / ** Nomor*/ Private Long ID; / ** Nama*/ nama string privat; / ** Usia*/ usia bilangan bulat pribadi; / ** Deskripsi*/ Deskripsi String Pribadi; / ** Waktu Pembuatan*/ Private String CreatetM; // Getter and Setter dihilangkan}Saat menggunakan SpringData, ia perlu mengatur IndexName dan mengetikkan kelas entitas. Jika dibandingkan dengan database tradisional, itu setara dengan perpustakaan dan tabel.
Perlu dicatat bahwa baik indexName dan tipe harus dalam huruf kecil !!!
Lapisan dao
Public Interface Userdao Extends ElasticsearchRepository <user, long> {}Lapisan DAO relatif sederhana di sini, cukup mewarisi kelas ElasticsearchRepository. Metode utama adalah Simpan, Hapus dan Cari. Metode Simpan sangat seperti memasukkan dan memperbarui. Jika tidak ada, itu akan ditambahkan dan jika ada, itu akan dibahas. Metode Hapus terutama untuk menghapus data dan perpustakaan indeks. Adapun pencarian, ini adalah kueri, termasuk beberapa pertanyaan yang umum digunakan, seperti pagination, bobot, dll.
Lapisan Layanan
@ServicePublic kelas UserserServiceImpl mengimplementasikan UserserService {@Autowired private userdao userdao; @Override Public Boolean Insert (pengguna pengguna) {boolean falg = false; coba {userdao.save (user); falg = true; } catch (Exception e) {E.PrintStackTrace (); } return falg; } @Override Daftar Publik <User> Search (String SearchContent) {QueryStringQueryBuilder Builder = baru QueryStringQueryBuilder (SearchContent); System.out.println ("Pernyataan kueri:"+pembangun); Iterable <user> searchResult = userdao.search (builder); Iterator <user> iterator = searchResult.iterator (); Daftar <User> Daftar = ArrayList baru <User> (); while (iterator.hasnext ()) {list.add (iterator.next ()); } daftar pengembalian; } @Override Daftar Publik <User> SearchUser (Integer Pagenumber, Integer Pagesize, String SearchContent) {// Parameter Pagination Pageable Pageable = PageRequest Baru (Pagenumber, PageSize); QueryStringQueryBuilder Builder = queryStringQueryBuilder baru (SearchContent); SearchQuery SearchQuery = NEW NATIONSECHQUERYBUILDER (). WithPageable (PAGABLE) .withQuery (Builder) .build (); System.out.println ("Pernyataan Kueri:" + SearchQuery.GetQuery (). ToString ()); Halaman <User> SearchPagerEsults = userdao.search (SearchQuery); kembalikan SearchPageresults.getContent (); } @Override Daftar Publik <User> SearchUserByWeight (String SearchContent) {// Query Menurut Fungsi BobotsCorequiller FunctionCoreQueryBuilder = queryBuilders.functionsCoreQuery () .add (querybuilders.boolQuery (). Harus (QUDERBUDER), QUIDCERS. ScorefunctionBuilders.WeightFactorFunction (10)) .add (querybuilders.boolQuery (). Harus (querybuilders.matchQuery ("description", searchContent)), scorefunctionBuilders.weightfactorFunction (100)). SetMinscore (2); System.out.println ("Pernyataan Kueri:" + FunctionsCoreQueryBuilder.tostring ()); Iterable <user> searchResult = userdao.search (functionsCorequeryBuilder); Iterator <user> iterator = searchResult.iterator (); Daftar <User> Daftar = ArrayList baru <User> (); while (iterator.hasnext ()) {list.add (iterator.next ()); } daftar pengembalian; }}Di sini saya hanya menulis beberapa metode, metode utama adalah kueri. Kueri termasuk pencarian teks lengkap, kueri pagination, dan kueri berat. Apa yang perlu dijelaskan adalah kueri berat. Semakin tinggi skor berat, semakin tinggi hasil kueri. Jika tidak ada skor yang ditetapkan untuk data lain, skor default mereka adalah 1. Jika Anda tidak ingin menanyakan pernyataan ini, cukup gunakan SetMinscore untuk mengaturnya ke lebih dari 1.
Pengujian Kode
Panggil antarmuka untuk menambahkan data
Data Baru:
Posting http: // localhost: 8086/API/user {"id": 1, "name": "Zhang San", "Age": 20, "Deskripsi": "Zhang San adalah insinyur pengembangan Java", "createTm": "2018:" Li Li San 11:07:42 "} {" ID ":" Li ":" Li ":" Li ":" Li ":" Li "Li. SI adalah insinyur uji "," createtm ":" 1980-2-15 19:01:32 "} {" id ": 3," name ":" wang wu "," zaman ": 25," deskripsi ":" wang wu adalah insinyur operasi dan pemeliharaan "," createTm ":" 2016-8-21 06:11:11:32 ""} "}"} "-8-21 06:11:11:11:32 "}"}}}}, "2016-8-21 06:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:32" Melakukan kueri teks lengkap
bertanya
http: // localhost: 8086/API/pengguna? SearchContent = Engineer
kembali
[{"id": 2, "name": "Li si", "Age": 14, "Deskripsi": "Li Si adalah insinyur uji", "createtm": "1980-2-15 19:01:32"}, {"id": 1, "name": "zhang san", "era": 20, "deskripsi" "" zhang "zhang san san" zhang san "," era ": 20," deskripsi "" "zhang zhang a san a san" zaman "": 20, "DESKRIPS" ":" ZHANG "ZHANG SAN ADALAH SAN" ZHANG SAN "," 20, "20," " "2018-4-25 11:07:42"}, {"id": 3, "Name": "Wang Wu", "Age": 25, "Deskripsi": "Wang Wu adalah insinyur operasi dan pemeliharaan", "createtm": "2016-8-21 06:11:32"}}]] Melakukan kueri pagination
bertanya
http: // localhost: 8086/API/user? Pagenumber = 0 & pageSize = 2 & SearchContent = Engineer
kembali
[{"id": 2, "name": "li si", "usia": 14, "deskripsi": "li si adalah insinyur uji"}, {"id": 1, "name": "Zhang San", "Age": 20, "Deskripsi": "Zhang San adalah insinyur pengembangan Java"}}] Lakukan kueri berat badan
bertanya
http: // localhost: 8086/API/user2? SearchContent = Li si
kembali
[{"id": 2, "name": "li si", "usia": 24, "deskripsi": "li si adalah insinyur uji", "createtm": "1980-2-15 19:01:32"}]Pernyataan cetak kueri berat:
Pernyataan kueri: {{"function_score": {"functions": [{"filter": {"bool": {"bool": {"harus": {"match": {"name": {"}}}} {" {"{" {"{" {"{" {"{" {" "bool": {"harus": {"match": {"description": {"kueri": "li si", "type": "boolean"}}}}}}, "bobot": 100.0}], "min_score": 2.0}}Catatan: Dalam tes, karena berat minimum SetMinscore diatur untuk dibagi menjadi 2, data yang tidak relevan tidak akan ditampilkan. Jika Anda ingin menampilkannya, cukup hapus dalam kode.
Setelah menambahkan data baru, Anda dapat memasukkan: http: // localhost: 9200/_plugin/head/di browser
Kemudian klik kueri dasar untuk melihat data yang ditambahkan. Jika Anda ingin menggunakan kueri pernyataan, Anda dapat menempelkan pernyataan kueri yang dicetak oleh konsol dalam program ke antarmuka kueri untuk kueri!
Catatan: Saya menginstal Elasticsearch di sini di Windows dan menginstal kepala plugin ES. Langkah -langkah instalasi spesifik adalah di akhir artikel.
Selain SpringData, sebenarnya ada metode lain untuk mengoperasikan Elasticsearch.
Misalnya, gunakan API Native Elasticsearch dan gunakan kelas TransportClient untuk mengimplementasikannya.
Atau gunakan untuk merangkum dengan musim semi, cukup suntikkan kacang di lapisan layanan.
Contoh:
@Autowired ElasticsearchTemplate ElasticsearchTemplate;
Namun, metode di atas memiliki keterbatasannya, yaitu, karena versi Elasticsearch diubah, Java API yang relevan juga terus-menerus menyesuaikan, yaitu, setelah versi server Elasticsearch diubah, kode klien mungkin perlu ditulis ulang.
Oleh karena itu, ia memperkenalkan alat perak pihak ketiga yang sangat berguna. Ini merangkum Elasticsearch dan mengisi kesenjangan dalam klien antarmuka Elasticsearch HTTPREST. Ini cocok untuk versi Elasticsearch 2.x atau di atas, dan tidak perlu mengubah kode karena perubahan versi server Elasticsearch!
JestClient
Pertama tambahkan dependensi berikut di Maven:
<dependency> <GroupId> io.searchbox </groupid> <ArTifactId> Jest </artifactId> <version> 5.3.3 </version> </dependency>
Kemudian tulis kode uji yang relevan.
Komentar dalam kode harus sangat lengkap, jadi saya tidak akan berbicara terlalu banyak tentang kode di sini.
Impor java.util.arraylist; impor java.util.list; impor org.elasticsearch.index.query.querybuilders; impor org.elasticsearch.search.builder.searchsourceBuilder; impor com.pancm.pojo.user; impor io.searchbox.searchbox.sclient; io.searchbox.client.jestclientfactory; impor io.searchbox.client.jestresult; impor io.searchbox.client.config.httpclientConfig; impor io.searchbox.core.bulk; Impor. io.searchbox.core.documentResult; impor io.searchbox.core.index; impor io.searchbox.core.search; impor io.searchbox.indices.createindex; import io.searchbox.indices.deleteIndex; impor io.searchbox.indices.mappapping Jesttest {Private Static JestClient JestClient; Private Static String IndexName = "UserIndex"; // Private Static String IndexName = "UserIndex2"; Private Static String typename = "user"; Private Static String Elasticips = "http://192.169.2.98:9200"; // Private Static String Elasticips = "http://127.0.0.1:9200"; public static void main (string [] args) melempar Exception {JestClient = getJestClient (); insertBatch (); serach1 (); serach2 (); serach3 (); jestclient.close (); } private static JestClient getJestClient () {JestClientFactory factory = new JestClientFactory (); factory.setHttpClientConfig (httpclientconfig.builder baru (elasticips) .conntimeout (60000) .readtimeout (60000) .multithreaded (true) .build ()); return factory.getObject (); } public static void insertBatch () {list <pes Object> objs = ArrayList baru <POMPERTIF> (); objs.add (pengguna baru (1L, "Zhang San", 20, "Zhang San adalah insinyur pengembangan Java", "2018-4-25 11:07:42"))); objs.add (pengguna baru (2L, "Li Si", 24, "Li Si adalah insinyur uji", "1980-2-15 19:01:32")); objs.add (pengguna baru (3L, "Wang Wu", 25, "Wang Wu adalah insinyur operasi dan pemeliharaan", "2016-8-21 06:11:32")); Hasil boolean = false; coba {result = insertBatch (JestClient, IndexName, Typename, OBJS); } catch (Exception e) {E.PrintStackTrace (); } System.out.println ("Batch Baru:"+Hasil); } / *** Pencarian teks lengkap* / public static void serach1 () {string query = "engineer"; coba {SearchSourceBuilder SearchSourceBuilder = new SearchSourceBuilder (); SearchSourceBuilder.Query (QueryBuilders.QueryStringQuery (Query)); // Pengaturan halaman SearchSourceBuilder.from (0) .Size (2); System.out.println ("Pernyataan kueri pencarian teks lengkap:"+SearchSourceBuilder.toString ()); System.out.println ("Pencarian Teks Lengkap Hasil Pengembalian:"+Cari (JestClient, IndexName, Typename, SearchSourceBuilder.ToString ())); } catch (Exception e) {E.PrintStackTrace (); }} / *** Pencarian yang tepat* / public static void serach2 () {coba {SearchSourceBuilder SearchSourceBuilder = new SearchSourceBuilder (); SearchSourceBuilder.Query (QueryBuilders.termQuery ("Age", 24)); System.out.println ("Pernyataan kueri pencarian yang tepat:"+SearchSourceBuilder.toString ()); System.out.println ("Exact Search Returns Hasil:"+Search (JestClient, IndexName, Typename, SearchSourceBuilder.ToString ())); } catch (Exception e) {E.PrintStackTrace (); }} / *** Pencarian interval* / public static void serach3 () {string createTm = "createTm"; String from = "2016-8-21 06:11:32"; String to = "2018-8-21 06:11:32"; coba {SearchSourceBuilder SearchSourceBuilder = new SearchSourceBuilder (); SearchSourceBuilder.Query (querybuilders.rangeQuery (createTm) .gte (from) .lte (to)); System.out.println ("Pernyataan Pencarian Interval:"+SearchSourceBuilder.ToString ()); System.out.println ("Interval Search Returns Hasil:"+Search (JestClient, IndexName, Typename, SearchSourceBuilder.ToString ())); } catch (Exception e) {E.PrintStackTrace (); }} / ** * Buat indeks * @param indexname * @return * @throws Exception * / public boolean createIndex (JestClient JestClient, String IndexName) Melempar Exception {Jestresult JR = JestClient.Execute (CreateIndex.Builder baru (indexName) .build ());); return jr.issuceded (); } /** * New data* @param indexName * @param typeName * @param source * @return * @throws Exception */ public boolean insert(JestClient jestClient,String indexName, String typeName, String source) throws Exception { PutMapping putMapping = new PutMapping.Builder(indexName, typeName, source).build(); Jestresult Jr = JestClient.Execute (putmapping); return jr.issuceded (); } / ** * Data kueri * @param indexName * @param typename * @return * @throws Exception * / public static string getIndexmapping (JestClient JestClient, String IndexName, String Typename) Lempar (GetMapping GetMapping = GetMapping.builder (). AddInDex (GetMapping. Jestresult Jr = JestClient.Execute (GetMapping); return jr.getjsonstring (); } / ** * Tambahkan data dalam batch * @param indexname * @param typename * @param objs * @return * @throws Exception * / public static boolean insertBatch (JestClient JestClient, String IndexName, String Typename, Daftar <Object> Objs) Lempar Pengecualian {Bulk.Builder Bulk.builder = Daftar = Objek> Objs) Lempar Exception {Bulk.Builder BENDERDER = Daftar = Objjs) Lemparan New Exception {Bulk.builder Bulk. Bulk.builder (). DefaultIndex (indexName) .defaultType (typename); untuk (objek obj: objs) {index index = new index.builder (obj) .build (); bulk.addaction (indeks); } Bulkresult br = jestclient.execute (bulk.build ()); return br.issuceded (); } / ** * Pencarian Teks Lengkap * @param IndexName * @param typename * @param kueri * @return * @throws Exception * / pencarian string statis public (JestClient JestClient, String IndexName, String Typename, String Query) Lempar Exception {Search Search = New Search.Builder (Query) .addindex) (LOVERN) (pencarian baru. Jestresult Jr = JestClient.Execute (Search); // System.out.println ("-"+jr.getjsonstring ()); // System.out.println ("-"+jr.getSourceAsObject (user.class)); return jr.getSourceAsstring (); } / ** * Hapus indeks * @param indexName * @return * @throws Exception * / public boolean delete (JestClient JestClient, String IndexName) Melempar Exception {Jestresult JR = JestClient.Execute (new deleteIndex.builder (indexName) .build ()); return jr.issuceded (); } / ** * Hapus data * @param indexname * @param typename * @param id * @return * @throws Exception * / public boolean delete (JestClient JestClient, String IndexName, String Typename, String ID) Lempar Pengecualian {DocumentResult DR = JestClient.Execute (New Delete.builder (id) .index (indexName) .type (typename) .build ()); return Dr.issuceded (); }Catatan: Sebelum pengujian, mari kita jelaskan bahwa versi Elasticsearch yang diinstal pada sistem Windows lokal adalah 2.3.5, dan versi Elasticsearch yang diinstal pada server Linux adalah 6.2.
Hasil tes
Pencarian Teks Lengkap
Pernyataan kueri pencarian teks lengkap: {"from": 0, "size": 2, "query": {"query_string": {"kueri": "engineer"}}} pencarian teks lengkap hasil pengembalian: {"id": 1, "name": "zhang san", "": 20, "Deskripsi": "Zhang San A adalah A JANG SAN", "": 20, "Deskripsi": "Zhang San A adalah A Jang San", "": 20, "Deskripsi": "Zhang San A adalah A JAGA SAN" "": 20, "Deskripsi": "Zhang San A adalah A JANG SAN", "": 20, "DESKRIP": "ZHANG SAN ADAL insinyur "," createtm ":" 2018-4-25 11:07:42 "}, {" id ": 2," name ":" li si "," usia ": 24," deskripsi ":" li si adalah insinyur uji "," createtm ":" 1980-2-15 19:01:32 "}Pencarian pencocokan
Pernyataan kueri pencarian yang akurat: {"kueri": {"istilah": {"usia": 24}}} pencarian yang akurat menghasilkan hasil: {"id": 2, "name": "li si", "usia": 24, "deskripsi": "li si adalah insinyur uji", "createTm": "1980-2-15 19:01:3.32Pencarian interval waktu
Pernyataan Pencarian Interval: {"Query": {"range": {"createTm": {"from": "2016-8-21 06:11:32", "to": "2018-8-21 06:11:32", "include_lower": true, "include_upper": true}}} "" "" "" "" "" "" "" "" name: "1," ID} "1," SAN "," Usia ": 20," Deskripsi ":" Zhang San adalah insinyur pengembangan Java "," createtm ":" 2018-4-25 11:07:42 "}Setelah menambahkan data baru, kita dapat pergi ke Linux Kibana untuk melakukan kueri terkait, dan hasil kueri adalah sebagai berikut:
Catatan: Kibana adalah perangkat lunak open source di rusa. Kibana menyediakan antarmuka web yang ramah analisis log untuk Logstash dan Elasticsearch untuk membantu meringkas, menganalisis, dan mencari log data penting.
Hasil yang dikembalikan oleh tes dalam kode di atas sejalan dengan harapan kami. Di antara mereka, hanya sebagian kecil dari JestClient yang digunakan. Untuk penggunaan lebih lanjut, Anda dapat memeriksa dokumentasi resmi JestClient.
Instal Elasticsearch di Windows
1. Persiapan dokumen
Alamat unduhan: https://www.elastic.co/downloads
Pilih versi terkait Elasticsearch, lalu pilih file zip nama akhiran untuk diunduh, dan kemudian unzip setelah diunduh.
2. Mulai Elasticsearch
Pergi ke Direktori Bin dan Jalankan elasticsearch.bat
Kemudian masukkan: localhost: 9200 di penjelajahan
Berhasil menampilkan antarmuka berarti kesuksesan!
3. Instal ES Plug-in
Instalasi Kepala Antarmuka Manajemen Web
Masukkan direktori bin, buka CMD, dan masukkan antarmuka DOS
Masukkan: plugin install mobz/elasticsearch-head
Lakukan Unduh
Setelah berhasil diunduh, masukkan: http: // localhost: 9200/_plugin/head/
Jika antarmuka ditampilkan, instalasi akan berhasil!
4. Daftar Layanan
Masukkan direktori bin, buka CMD, dan masukkan antarmuka DOS
Memasuki:
Layanan.bat installservice.bat mulai
Setelah sukses, masukkan
services.msc
Lompat ke antarmuka layanan layanan untuk melihat status ES yang berjalan secara langsung!
lainnya
Alamat API Situs Web Resmi Elasticsearch:
https://www.elastic.co/guide/en/elasticsearch/client/java-api/2.3/index.html
Alamat JestClientGithub:
https://github.com/searchbox-oo/jest (unduhan lokal)
Saya menempatkan proyek di GitHub.
https://github.com/xuwujing/springboot (unduhan lokal)
Meringkaskan
Di atas adalah seluruh konten artikel ini. Saya berharap konten artikel ini memiliki nilai referensi tertentu untuk studi atau pekerjaan semua orang. Jika Anda memiliki pertanyaan, Anda dapat meninggalkan pesan untuk berkomunikasi. Terima kasih atas dukungan Anda ke wulin.com.