1。記事のコンテンツを検索するためのアイデア
前の記事では、Spring Boot 2.0にES 5を統合する方法について説明しました。この記事では、特定の実用的な措置について説明しています。記事や質問や回答の具体的な実装を実装する方法について簡単に説明しましょう。実装のアイデアは非常に簡単です:
ここで直接検索を呼び出すと、不十分なものを簡単に見つけることができます。コンテンツ検索はコンテンツの接続に焦点を当てているためです。したがって、ここでの処理方法は比較的低いので、より多くの通信を備えたより良い検索方法を実現したいと考えています。単語分詞を介して多くのフレーズを取得し、フレーズを使用してフレーズを正確に一致させることです。
IK Word ScemederプラグインのESインストールは非常に簡単です。最初のステップは、対応するバージョンhttps://github.com/medcl/elasticsearch-analysis-ik/releasesをダウンロードすることです。 2番目のステップは、ElasticSearch-5.5.3/Plugins Directoryに新しいフォルダーIKを作成し、ElasticSearch-Analysis-IK-5.5.5.3.zipの未zipファイルをElasticSearch-5.1.1/Plugins/IKディレクトリにコピーすることです。最後にESを再起動します。
2。コンテンツ分詞を検索します
IKをインストールして、それを呼び出す方法は?
最初のステップは、ここでコンテンツを検索するとき、コンマスプライシングでそれを渡すことです。したがって、コンマは最初に分割されます
2番目のステップは、検索用語に自分自身を追加することです。
3番目のステップは、IK分詞の後にAnalyzereQuestBuilderオブジェクトを使用してReturn Valueオブジェクトリストを取得することです
ステップ4:分詞の結果を最適化します。たとえば、すべてが単語の場合は、すべてを維持します。言葉と言葉がある場合は、言葉を保持します。言葉だけがある場合は、言葉を保持します。
コア実装コードは次のとおりです。
/ ***検索コンテンツ分詞*/保護されたリスト<String> HandLingsearchContent(String SearchContent){List <String> SearchTermResultList = new ArrayList <>(); //検索用語リスト<string> searchtermlist = arrays.aslist(searchconstant.split(searchconstant.string_token_split))を取得するには、コンマで分割されます。 //検索用語が1つの単語を超える場合、IKワード分詞はWord分詞resultリストsearchtermlist.foreach(//検索用語リスト自体を追加し、検索タームresultlist.add(searchterm); //検索用語を取得します。 }); SearchTermResultListを返します。 } / *** esを呼び出してIK分詞の後に結果を取得します* /保護されたリスト<string> getikanalyzesearchterms(string searchcontent){analyzerequestbuilder ikrequest = new analyzerequestbuilder(elasticsearchtemplate.getclient()、analyzeAction.instance、searchconstant.index_named.instant.instance、earzeAction。 ikrequest.settokenizer(searchconstant.tokenizer_ik_max);リスト<Analyzeresponse.Analyzetoken> iktokenList = ikrequest.execute()。actionget()。getTokens(); //ループ割り当てリスト<String> SearchTermList = new ArrayList <>(); iktokenlist.foreach(iktoken-> {searchtermlist.add(iktoken.getterm());}); return handlingikResultterms(searchtermlist); } / ** *単語分詞の結果:シャンプー(シャンプー、髪、シャンプー、髪、水) * - すべての単語であり、単語 +単語のみを保持します * - すべての単語であり、単語を維持します * /プライベートリスト<文字列<文字列<文字列<文字列> searchterterist){boolean isphrase = false; boolean isword = false; for(string term:searchtermlist){if(term.length()> searchconstant.search_term_length){isphrase = true; } else {isword = true; }} if(isword&isphrase){list <string> fraseList = new arrayList <>(); searchtermlist.foreach(term-> {if(term.length()> searchconstant.search_term_length){fraseList.add(ターム);}});戻りフラセリスト; } return searchtermlist; }3。クエリステートメントを検索します
コンテンツ列挙オブジェクトを構築し、検索する必要があるフィールドをリストします。 ContentSearch TermeNumコードは次のとおりです。
Lombok.AllargSconstructor; @allargsconstructorpublic enum contentsearchtermenum {// title title( "title")、// content content( "content"); / ***フィールド検索*/プライベート文字列名。 public string getName(){return name; } public void setName(string name){this.name = name; }}「電話検索マッチ」検索フィールドをループし、最小重量値を1に設定します。コアコードは次のとおりです。
/ *** construct query条件*/ private void buildmatchquery(boolquerybuilder querybuilder、list <string> searchtermlist){for(string searchterm:searchtermlist){for(contentsearchtermenum searchtermenum:contentsearchtermenum.values(){{ querybuilder.should(querybuilders.matchphrasequery(searchtermenum.getname()、searchterm)); }} querybuilder.minimumshouldmatch(searchconstant.minimum_should_match); }4。フィルター条件
検索するものが複数あり、時には需要がこのようなものです。 eコマースなど、特定のブランドの下で製品を検索する必要があるなど、特定のカテゴリで検索する必要があります。その後、フィルタリングのためにいくつかのフィットラーを構築する必要があります。 SQLステートメントに対応しています。フィルターメソッドを使用して、ESにフィルタリングを追加します。コードは次のとおりです。
/ ***ビルドフィルター*/ private void buildfilterquery(boolquerybuilder boolquerybuilder、integer type、string category){//コンテンツタイプフィルターif(type!= null){boolquerybuilder typefilterbuilder = querybuilders.boolquery(); TypeFilterBuilder.shows(querybuilders.matchquery(searchconstant.type_name、type).lenient(true)); boolquerybuilder.filter(typefilterbuilder); } //コンテンツカテゴリフィルターif(!stringutils.isempty(category)){boolquerybuilder categoryfilterbuilder = querybuilders.boolquery(); categoryfilterbuilder.shows(querybuilders.matchquery(searchconstant.category_name、category).lenient(true)); boolquerybuilder.filter(categoryfilterbuilder); }}タイプは大規模なクラスで、カテゴリは小さなクラスであるため、サイズとクラスのフィルタリングをサポートできます。しかし、Type = 1またはType = 2で検索する必要がある場合はどうなりますか?特定の実装コードは非常に簡単です:
typefilterbuilder .should(querybuilders.matchquery(searchconstant.type_name、1)。
チェーン式を介して、2つは実装する必要があります。つまり、SQLに対応するORステートメントを実装する必要があります。 SQLに対応するStatementの実装は、2つのBoolqueryBuildersを通じて達成されます。
5。ページングと並べ替え条件
ページングソートコードは非常に簡単です:
@Override public pagebean searchContent(contentsearchbean contentsearchbean){integer pagenumber = contentsearchbean.getPageNumber(); integer pagesize = contentsearchbean.getPagesize(); pagebean <contententity> resultPageBean = new PageBean <>(); resultPagebean.setPageNumber(PageNumber); resultPagebean.setPagesize(Pagesize); //検索フレーズ文字列searchcontent = contentsearchbean.getSearchContent(); List <String> searchTertermList = HandLingsearchContent(searchContent); //クエリ条件を構築するboolquerybuilder boolquerybuilder = querybuilders.boolquery(); BuildMatchQuery(boolquerybuilder、searchtermlist); //フィルター条件のビルドBuildFilterQuery(boolquerybuilder、contentsearchbean.getType()、contentsearchbean.getcategory()); //ページングおよびソート条件を構築するpageable pageable = pagerequest.of(pagenumber、pageize); if(!stringutils.isempty(contentsearchbean.getOrderName())){pageable = pagerequest.of(pageNumber、pagesize、sort.direction.desc、contentsearchbean.getOrderName()); } SearchQuery SearchQuery = new NativesearchQueryBuilder()。 // search logger.info( " /n contentserviceimpl.searchContent()[" + searchContent + "] /n dsl = /n" + searchQuery.getQuery()。toString());ページ<ContentEntity> contentPage = contentRepository.search(searchQuery); resultPagebean.setResult(contentpage.getContent()); resultPagebean.settotalcount((int)contentpage.getTotalements()); resultPagebean.settotalpage((int)contentpage.getTotalements()); resultPagebean.settotalpage((int)contentpage.getTotalelements() / resultPagebean.getPagesize() + 1); runter resultPageBean; }ページ可能なオブジェクトを使用して、ページングパラメーターを構築し、対応するソートフィールドとソート順序(DESC ASC)を指定します。
6。概要
このアイデアは比較的簡単です。私はそれがすべての人の学習に役立つことを願っています、そして、私は誰もがwulin.comをもっとサポートすることを願っています。