序文
前の記事では、Springboot、MyBatis、Druid、PageHelperが統合され、複数のデータソースの操作が実装されました。この記事では、主に最も人気のある検索エンジンであるElastisearchを紹介および使用し、Springbootと組み合わせて使用します。
ElasticSearchの紹介
ElasticSearchは、Luceneに基づく検索サーバーです。実際にLuceneをカプセル化し、REST APIの操作インターフェイスを提供します。 ElasticSearchは、非常にスケーラブルなオープンソースフルテキスト検索および分析エンジンであり、ビッグデータをすばやく保存、検索、分析するために使用できます。
ElasticSearchの主な機能:分散型、高可用性、非同期ライティング、マルチAPI、ドキュメント指向。
ElasticSearchコアコンセプト:リアルタイム近く、クラスター、ノード(データの保存)、インデックス、シャード(スライスインデックスシャード)、レプリカ(スライシングは複数のレプリカを設定できます)。大量のデータをすばやく保存、検索、分析できます。
ElasticSearchユースケース:Wikipedia、Stack Overflow、Githubなど。
SpringbootはElasticSearchを統合します
Springbootを使用してElasticsearchを統合する前に、それらの間の関係を理解する必要があります。
| スプリングブートバージョン(x) | Spring Data Elasticsearchバージョン(Y) | 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 ** |
ここで使用しているスプリングブートのバージョンは1.5.9で、Elasticsearchのバージョンは2.3.5です。
Springbootを使用してElasticsearchを統合すると、一般にSpringDataを使用してカプセル化され、DAOレイヤーインターフェイスがElasticSearchRepositoryクラスを継承します。このクラスは、一般的に使用されるCRUDメソッドなど、多くの方法を実装しています。
Springdataの使用
まず、使用する前に関連する準備をします。
Mavenの構成は次のとおりです。
<依存関係> groupId> org.springframework.boot </groupid> <artifactid> spring-boot-starter-web </artifactid> <バージョン> 1.5.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.Springframework.boot </groupid> <artifactid> spring-boot-starter-data-elasticsearch </artifactid> <バージョン> 1.5.9.release </version> </dependency>
Application.Propertiesの構成
spring.data.elasticsearch.repositories.enabled = truespring.data.elasticsearch.cluster-nodes = 127.0.0.1/:9300
注: 9300はJavaクライアントのポートです。 9200は、Restful HTTPをサポートするインターフェイスです。
その他の構成:
spring.data.elasticsearch.cluster-name elasticsearchクラスター名。 (デフォルト:ElasticSearch)
spring.data.elasticsearch.cluster-nodesコンマで区切られたクラスターノードアドレスのリスト。指定されていない場合は、クライアントノードを起動します。
spring.data.elasticsearch.propertieは、クライアントの追加プロパティを構成するために使用されます。
spring.data.elasticsearch.repositories.enabled elasticsearchリポジトリを有効にします。 (デフォルト:true。)
コードライティング
エンティティクラス
@document(indexname = "userindex"、type = "user")パブリッククラスユーザーはserializable { / ** * * / private static final long serialversionuid = 1l; / ** number*/ private long id; / **名前*/プライベート文字列名; / **年齢*/民間整数年齢。 / **説明*/プライベート文字列の説明; / **作成時間*/ private string createTM; // getterとsetter省略}SpringDataを使用する場合、インデックス名を設定してエンティティクラスに入力する必要があります。従来のデータベースと比較すると、ライブラリやテーブルに相当します。
インデックス名とタイプの両方が小文字にある必要があることに注意する必要があります!!!
ダオ層
パブリックインターフェイスuserdaoはelasticsearchrepository <user、long> {}を拡張しますここではDAO層が比較的単純で、ElasticSearchRepositoryクラスを継承するだけです。主な方法は、保存、削除、検索です。保存方法は、挿入と更新のようなものです。 noがある場合、それは追加され、それがある場合、それはカバーされます。削除方法は、主にデータとインデックスライブラリを削除するためです。検索に関しては、ページネーション、ウェイトなどの一般的に使用されるクエリを含むクエリです。
サービスレイヤー
@servicepublic class userserviceimpl emplence userservice {@autowired private userdao userdao; @Override public Boolean Insert(ユーザーユーザー){boolean falg = false; try {userdao.save(user); Falg = true; } catch(Exception e){e.printstacktrace(); }ファルグを返します。 } @Override public List <user> search(string searchContent){QueryStringQueryBuilder Builder = new QueryStringQueryBuilder(searchContent); system.out.println( "queryステートメント:"+ビルダー); iterable <user> searchResult = userdao.search(builder); iterator <user> iterator = searchResult.iterator();リスト<ユーザー> list = new arrayList <user>(); while(iterator.hasnext()){list.add(iterator.next()); }返品リスト。 } @Override public List <user> searchUser(integer pagenumber、integer pagesize、string searchcontent){//ページネーションパラメーターページ可能なpageable = new pagerequest(pagenumber、pageize); QueryStringQueryBuilder Builder = new QueryStringQueryBuilder(SearchContent); SearchQuery SearchQuery = new NativesearchQueryBuilder()。 system.out.println( "queryステートメント:" + searchQuery.getQuery()。toString());ページ<user> searchpageresults = userdao.search(searchQuery); return searchpageresults.getContent(); } @Override public List <user> searchUserbyweight(String SearchContent){// Weights functionscorequiller functionscorebuerybuilders.functionscorequery().add().add(querybuilders.boolquery()。 ScoreFunctionBuilders.WeightFactorFunction(10)).Add(queryBuilders.boolquery()。 system.out.println( "queryステートメント:" + functionscorequerybuilder.toString()); iterable <user> searchResult = userdao.search(functionscorequerybuilder); iterator <user> iterator = searchResult.iterator();リスト<ユーザー> list = new arrayList <user>(); while(iterator.hasnext()){list.add(iterator.next()); }返品リスト。 }}ここでは、単にいくつかの方法を書きました。主な方法はクエリです。クエリには、フルテキスト検索、ページネーションクエリ、重量クエリが含まれます。説明する必要があるのは、重量クエリです。重量スコアが高いほど、クエリの結果が高くなります。他のデータにスコアが設定されていない場合、デフォルトスコアは1です。これらのステートメントを照会したくない場合は、SetMinscoreを使用して1を超えるだけです。
コードテスト
インターフェイスを呼び出してデータを追加します
新しいデータ:
http:// localhost:8086/api/user {"id":1、 "name": "zhang san"、 "age":20、 "description": "Zhang SanはJava開発エンジニア"、 "createTM": "2018-4-25 11:07:42"} siはテストエンジニア "、" createtm ":" 1980-2-15 19:01:32 "} {" id ":3、" name ":" wang wu "、" age ":25、" description ":" wang wuは運用と維持エンジニア "、" createtm ":" 2016-8-21 06:11:32 "}}全文クエリを実施します
聞く
http:// localhost:8086/api/user?searchContent = Engineer
戻る
[{"id":2、 "name": "li si"、 "age":14、 "description": "li siはテストエンジニア"、 "createtm": "1980-2-15 19:01:32"}、{"id":1、 "name": "zhang san"、 "age": "zhang san": "zhang san"、 " "2018-4-25 11:07:42"}、{"id":3、 "name": "wang wu"、 "age":25、 "description": "wang wuは操作と保守エンジニア"、 "createtm": "2016-8-21 06:11:32"}]ページネーションクエリを実行します
聞く
http:// localhost:8086/api/user?pagenumber = 0&pagesize = 2&searchcontent = engineer
戻る
[{"id":2、 "name": "li si"、 "age":14、 "description": "li siはテストエンジニア"}、{"id":1、 "name": "zhang san"、 "age": "" description ":" Zhang San is a Java Development Engineer "}]]重量クエリを実行します
聞く
http:// localhost:8086/api/user2?searchcontent = li si
戻る
[{"id":2、 "name": "li si"、 "age":24、 "description": "li siはテストエンジニア"、 "createtm": "1980-2-15 19:01:32"}]]重量クエリ印刷ステートメント:
Queryステートメント:{{"function_score":{"functions":[{"filter":{bool ":{" bool ":{" seff ":{mate":{"name":{"query": "li si"、 "type": "boolean"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} "bool":{"suld":{"mate":{"description":{"query": "li si"、 "type": "boolean"}}}}}}}}}}}}}}}、 "min_score":2.0}}}}注:テストでは、SetMinscoreの最小重量が2に分割されるように設定されるため、無関係なデータは表示されません。表示したい場合は、コードで削除してください。
新しいデータを追加した後、http:// localhost:9200/_plugin/head/in the browserを入力できます
次に、基本クエリをクリックして、追加されたデータを表示します。ステートメントクエリを使用する場合は、プログラムのコンソールによって印刷されたクエリステートメントをクエリインターフェイスに貼り付けてクエリを貼り付けることができます。
注: WindowsにElasticSearchをここにインストールし、ESプラグインヘッドをインストールしました。特定のインストール手順は、記事の最後にあります。
Springdataに加えて、実際にはElasticSearchを操作する他の方法があります。
たとえば、ネイティブElasticsearch APIを使用し、TransportClientクラスを使用して実装します。
または、スプリングごとにカプセル化するために使用し、豆をサービスレイヤーに注入するだけです。
例:
@autowired elasticsearchtemplate elasticsearchtemplate;
ただし、上記の方法には制限があります。つまり、ElasticSearchのバージョンが変更されると、関連するJava APIも常に調整されています。つまり、ElasticSearchのサーバーバージョンが変更された後、クライアントのコードを書き直す必要がある場合があります。
したがって、非常に有用なサードパーティツールJestClientを紹介します。 ElasticSearchをカプセル化し、ElasticSearch httprestインターフェイスクライアントのギャップを埋めます。 ElasticSearch 2.x以下のバージョンに適しており、ElasticSearch Serverバージョンの変更によりコードを変更する必要はありません。
jestclient
まず、Mavenで次の依存関係を追加します。
<Dependency> groupId> io.searchbox </groupid> <artifactid> jest </artifactid> <version> 5.3.3 </version> </dependency>
次に、関連するテストコードを書きます。
コードのコメントは非常に完全である必要があるので、ここでコードについてあまり話しません。
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;import io.searchbox.client.JestClient;import io.searchbox.client.jestclientfactory; Import io.searchbox.client.jestresult; Import io.searchbox.client.config.httpclientconfig; Import io.searchbox.core.bulk; Import io.searchbox.core.bulkretult; io.searchbox.core.documentresult; import io.searchbox.core.index; import io.searchbox.core.search; import io.searchbox.indices.createindex; import io.searchbox.indices.deleteindex; import io.searchbox.indices.mapping.mapt.metmapt.mistemapt.mit.searchbox.indices. 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)スロー例外{jestclient = getJestClient(); insertBatch(); serach1(); serach2(); serach3(); jestclient.close(); } private static jestclient getJestClient(){JestClientFactory = new JestClientFactory(); Factory.sethttpclientconfig(new httpclientconfig.builder(elasticips).conntimeout(60000).readtimeout(60000).multithreaded(true).build()); return factory.getobject(); } public static void insertBatch(){list <object> objs = new arrayList <Object>(); Objs.Add(新しいユーザー(1L、 "Zhang San"、20、 "Zhang SanはJava開発エンジニア"、 "2018-4-25 11:07:42")); objs.add(新しいユーザー(2L、 "li si"、24、 "li siはテストエンジニア"、 "1980-2-15 19:01:32")); Objs.Add(新しいユーザー(3L、 "Wang Wu"、25、 "Wang Wuは運用および保守エンジニア"、「2016-8-21 06:11:32 ")); boolean result = false; try {result = insertBatch(jestclient、indexName、typename、objs); } catch(Exception e){e.printstacktrace(); } system.out.println( "batch new:"+result); } / ***フルテキスト検索* / public static void serach1(){string query = "engineer"; try {searchSourceBuilder SearchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.Query(querybuilders.querystringquery(query)); //ページSeartSourceBuilder.from(0).Size(2); system.out.println( "フルテキスト検索クエリステートメント:"+searchSourceBuilder.toString()); system.out.println( "フルテキスト検索結果の結果:"+search(jestclient、indexName、typename、searchSourceBuilder.toString())); } catch(Exception e){e.printstacktrace(); }} / *** exact search* / public static void serach2(){try {searchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.Query(queryBuilders.termquery( "age"、24)); System.out.println( "Exact Search Queryステートメント:"+searchSourceBuilder.toString()); system.out.println( "exact search returns result:"+search(jestclient、indexName、typename、searchSourceBuilder.toString())); } catch(Exception e){e.printstacktrace(); }} / *** interval search* / public static void serach3(){string createTm = "createTm"; string from = "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(from).lte(to)); system.out.println( "interval searchステートメント:"+searchSourceBuilder.toString()); system.out.println( "インターバル検索結果結果:"+search(jestclient、indexName、typename、searchSourceBuilder.toString())); } catch(Exception e){e.printstacktrace(); }} / ** * create index * @param indexname * @return * @throws例外 * / public boolean createIndex(jestclient jestclient、string indexname)スロー例外{jestResult Jr = jestclient.execute(new createindex.builder(indexname).build()); jr.issuceded(); } / ** *新しいデータ * @param indexname * @param typename * @param source * @return * @Return * / public boolean Insert(jestclient jestclient、string indexname、string typename、string source)スロー{putmapping putmapping = putmapping = new putmapping.builder(indexname、source、source、source).build(); JestResult JR = JestClient.Execute(PutMapping); jr.issuceded(); } / ** * query data * @param indexname * @param typename * @return * @throws例外 * / public static string getindexmapping(jestclient jestclient、string indexname、string typename)スロー例外{getMapping getMapping = getMapping = new getMapping.Builder()。 JestResult Jr = JestClient.Execute(getMapping); return jr.getjsonstring(); } / ** *バッチにデータを追加 * @param indexname * @param typename * @param objs * @return * @throws例外 * / public static boolean insertbatch(jestclient jestclient、string indexname、string typename、list <object> objs)スロー例bulk.builder()。defaultIndex(indexName).defaultType(typename); for(object obj:objs){index = new index.builder(obj).build(); bulk.addaction(index); } bulkResult br = jestclient.execute(bulk.build()); br.issuceded(); } / ** *フルテキスト検索 * @param indexname * @param typename * @param query * @return * / public static string search(jestclient jestclient、string indexname、string typename、string query)スロー例外jestresult jr = jestclient.execute(search); // system.out.println( " - "+jr.getjsonstring()); // system.out.println( " - "+jr.getSourceasobject(user.class)); return jr.getsourceasstring(); } / ** * delete index * @param indexname * @return * @throws例外 * / public boolean delete(jestclient jestclient、string indexname)スロー例外{jestresult jr = jestclient.execute(new deleteindex.builder(indexname).build()); jr.issuceded(); } / ** * delete data * @param indexname * @param typename * @param id * @return * @throws例外 * / public boolean delete(jestclient jestclient、string indexname、string typename、string id)slows exception {documentres dr = jestclient.execute(new(new delete.builder(id).index(indexname).type(typename).build()); dr.issucceeded()を返します。 }注:テスト前に、ローカルWindowsシステムにインストールされているElasticsearchバージョンが2.3.5であり、LinuxサーバーにインストールされているElasticsearchバージョンが6.2であることを最初に説明しましょう。
テスト結果
全文検索
フルテキスト検索クエリステートメント:{"from":0、 "size":2、 "query":{"query_string":{"query": "einger"}}}}}} returns results:{"id":1、 "name": "zhang san"、 "age":20、 "エンジニア "、" createtm ":" 2018-4-25 11:07:42 "}、{" id ":2、" name ":" li si "、" age ":24、" description ":" li siはテストエンジニア "、" createtm ":" 1980-2-15 19:01:32 "}}}一致する検索
正確な検索クエリステートメント:{"query":{"Term":{"age":24}}}正確な検索結果結果:{"id":2、 "name": "li si"、 "age":24、 ":" li siはテストエンジニア "、" createtm ":"時間間隔検索
インターバル検索ステートメント:{"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 results rest " san "、" age ":20、" description ":" Zhang SanはJava開発エンジニア "、" createtm ":" 2018-4-25 11:07:42 "}新しいデータを追加した後、Linux Kibanaにアクセスして関連クエリを実施できます。クエリの結果は次のとおりです。
注: KibanaはELKのオープンソースソフトウェアです。 Kibanaは、LogstashとElasticsearch用のログ分析に優しいWebインターフェイスを提供して、重要なデータログの要約、分析、検索を支援します。
上記のコードでテストによって返された結果は、私たちの期待に沿っています。その中で、Jestclientのごく一部のみが使用されています。その他の使用については、JestClientの公式文書を確認できます。
WindowsにElasticSearchをインストールします
1。ドキュメントの準備
住所をダウンロード:https://www.elastic.co/downloads
ElasticSearch関連バージョンを選択し、ダウンロードする接尾辞名zipファイルを選択し、ダウンロード後に解凍します。
2。ElasticSearchを開始します
Bin Directoryに移動し、 elasticsearch.batを実行します
次に、browse on the Browseに入力します
インターフェイスを正常に表示することは成功を意味します!
3。ESプラグインをインストールします
Web管理インターフェイスヘッドのインストール
Binディレクトリを入力し、CMDを開き、DOSインターフェイスを入力します
入力: plugin install mobz/elasticsearch-head
ダウンロードしてください
ダウンロードが成功した後、http:// localhost:9200/_plugin/head/を入力してください
インターフェイスが表示されると、インストールが成功します!
4.登録サービス
Binディレクトリを入力し、CMDを開き、DOSインターフェイスを入力します
入力:
service.bat installservice.bat start
成功した後、入力します
services.msc
ESの実行ステータスを直接表示するには、サービスサービスインターフェイスにジャンプしてください!
他の
ElasticSearch公式ウェブサイトAPIアドレス:
https://www.elastic.co/guide/en/elasticsearch/client/java-api/2.3/index.html
JestClientGithubアドレス:
https://github.com/searchbox-io/jest(ローカルダウンロード)
プロジェクトをGithubに置きました。
https://github.com/xuwujing/springboot(ローカルダウンロード)
要約します
上記は、この記事のコンテンツ全体です。この記事の内容には、すべての人の研究や仕事に特定の参照値があることを願っています。ご質問がある場合は、メッセージを残してコミュニケーションをとることができます。 wulin.comへのご支援ありがとうございます。