Spring Boot 2.0 integrates ES 5 Content Search practices, springes
Content of this Chapter
I. Search Ideas
The previous article talked about how to integrate ES 5 on Spring Boot 2.0. Let's briefly explain how to implement search for articles and Q &. The implementation is simple:
Set the minimum matching Weight Based on phrase matching
Which of the following phrases can be segmented by IK analyzer?
Filtering Based on Fiter
Pageable-based paging sorting
If you directly call the search method here, you can easily find unsatisfactory things. Because Content Search focuses on content connectivity. Therefore, the processing method here is relatively low, and we hope to achieve a better search method through multiple communications. It is to get a lot of phrases through word segmentation, and then use phrases for precise phrase matching.
Installing the IK splitter plug-in ES is simple. Step 1: Download the corresponding version https://github.com/medcl/elasticsearch-analysis-ik/releases. Step 2, under the elasticsearch-5.5.3/plugins directory, create a new folder ik and copy the files decompressed by the elasticsearch-analysis-ik-5.5.3.zip to the elasticsearch-5.1.1/plugins/ik directory. Restart ES.
Ii. Search content Segmentation
After IK is installed, how can I call it?
The first step is to splice the search content with commas. Therefore, the system splits the comma (,) first.
Step 2: Add yourself to the search term, because some words are lost after ik word segmentation... This is a bug.
Step 3: Use the AnalyzeRequestBuilder object to obtain the list of returned values after IK word splitting.
Step 4: optimize word segmentation results. For example, if all words are used, all words are retained. If there are words, words are retained. If only words are used, words are retained.
The core implementation code is as follows:
/*** Search content segmentation */protected List <String> handlingSearchContent (String searchContent) {List <String> searchTermResultList = new ArrayList <> (); // separate by commas, obtain the List of search terms <String> searchTermList = Arrays. asList (searchContent. split (SearchConstant. STRING_TOKEN_SPLIT); // if the search term is greater than 1 word, the list of word segmentation results searchTermList will be obtained through the IK token_split. forEach (searchTerm-> {// the search term TAG itself is added to the search term list and solves the problem of "will": searchTermResultList. add (searchTerm); // obtain the search term IK word segmentation list searchTermResultList. addAll (getIkAnalyzeSearchTerms (searchTerm);}); return searchTermResultList;}/*** call elasticsearch to obtain the IK word splitting result */protected List <String> getIkAnalyzeSearchTerms (String searchContent) {AnalyzeRequestBuilder ikRequest = new AnalyzeRequestBuilder (elasticsearchTemplate. getClient (), AnalyzeAction. INSTANCE, SearchConstant. INDEX_NAME, searchContent); ikRequest. setTokenizer (SearchConstant. TOKENIZER_IK_MAX); List <AnalyzeResponse. analyzeToken> ikTokenList = ikRequest.exe cute (). actionGet (). getTokens (); // cyclic value assignment List <String> searchTermList = new ArrayList <> (); ikTokenList. forEach (ikToken-> {searchTermList. add (ikToken. getTerm () ;}); return handlingIkResultTerms (searchTermList);}/*** if the word segmentation result is: Shampoo (shampoo, shampoo, and water) *-all words, reserved *-word + word, only reserved words *-all words, reserved words */private List <String> handlingIkResultTerms (List <String> searchTermList) {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> phraseList = new ArrayList <> (); searchTermList. forEach (term-> {if (term. length ()> SearchConstant. SEARCH_TERM_LENGTH) {phraseList. add (term) ;}}); return phraseList;} return searchTermList ;}
Iii. Search and query statements
Construct the content enumeration object and list the fields to be searched. The ContentSearchTermEnum code is as follows:
Import lombok. allArgsConstructor; @ AllArgsConstructorpublic enum ContentSearchTermEnum {// TITLE title ("TITLE"), // CONTENT ("content");/*** search field */private String name; public String getName () {return name;} public void setName (String name) {this. name = name ;}}
Loop through the phrase search and match search field, and set the minimum weight to 1. The core code is as follows:
/*** Construct query condition */private void buildMatchQuery (BoolQueryBuilder queryBuilder, List <String> searchTermList) {for (String searchTerm: searchTermList) {for (ContentSearchTermEnum searchTermEnum: ContentSearchTermEnum. values () {queryBuilder. shocould (QueryBuilders. matchPhraseQuery (searchTermEnum. getName (), searchTerm) ;}} queryBuilder. minimumShouldMatch (SearchConstant. MINIMUM_SHOULD_MATCH );}
Iv. Filtering Conditions
There are more than things found, and sometimes the demand is like this. You need to search under a certain category. For example, e-commerce companies need to search for products under a certain brand. Then we need to construct some fitler for filtering. Corresponds to the or and statements under the Where clause of the SQL statement. Use the filter method in ES to add a filter. The Code is as follows:
/*** Construct filtering condition */private void buildFilterQuery (BoolQueryBuilder boolQueryBuilder, Integer type, String category) {// content type filtering if (type! = Null) {BoolQueryBuilder typeFilterBuilder = QueryBuilders. boolQuery (); typeFilterBuilder. shocould (QueryBuilders. matchQuery (SearchConstant. TYPE_NAME, type ). lenient (true); boolQueryBuilder. filter (typeFilterBuilder);} // content category filter if (! StringUtils. isEmpty (category) {BoolQueryBuilder categoryFilterBuilder = QueryBuilders. boolQuery (); categoryFilterBuilder. shocould (QueryBuilders. matchQuery (SearchConstant. CATEGORY_NAME, category ). lenient (true); boolQueryBuilder. filter (categoryFilterBuilder );}}
Type is a large category, and category is a small class, so that large and small classes can be filtered. But what if you need to search in type = 1 or type = 2? The specific implementation code is simple:
typeFilterBuilder .should(QueryBuilders.matchQuery(SearchConstant.TYPE_NAME, 1) .should(QueryBuilders.matchQuery(SearchConstant.TYPE_NAME, 2) .lenient(true));
Using a chained expression, two shoders implement OR, that is, the OR statement corresponding to SQL. Two BoolQueryBuilder methods are used to implement AND, that is, the AND statement corresponding to SQL.
5. Paging and sorting Conditions
The paging sorting code is simple:
@ 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); // construct the search phrase String searchContent = contentSearchBean. getSearchContent (); List <String> searchTermList = handlingSearchContent (searchContent); // construct the query condition BoolQueryBuilder boolQueryBuilder = QueryBuilders. boolQuery (); buildMatchQuery (boolQueryBuilder, searchTermList); // construct a filter condition buildFilterQuery (boolQueryBuilder, contentSearchBean. getType (), contentSearchBean. getCategory (); // construct pagination and sort condition Pageable pageable = PageRequest. of (pageNumber, pageSize); if (! StringUtils. isEmpty (contentSearchBean. getOrderName () {pageable = PageRequest. of (pageNumber, pageSize, Sort. direction. DESC, contentSearchBean. getOrderName ();} SearchQuery searchQuery = new NativeSearchQueryBuilder (). withPageable (pageable ). withQuery (boolQueryBuilder ). build (); // search for LOGGER.info ("\ n ContentServiceImpl. searchContent () ["+ searchContent +"] \ n DSL = \ n "+ searchQuery. getQuery (). toString (); Page <ContentEntity> contentPage = contentRepository. search (searchQuery); resultPageBean. setResult (contentPage. getContent (); resultPageBean. setTotalCount (int) contentPage. getTotalElements (); resultPageBean. setTotalPage (int) contentPage. getTotalElements ()/resultPageBean. getPageSize () + 1); return resultPageBean ;}
Use the Pageable object to construct the paging parameters, specify the corresponding sorting fields, and sort order (desc asc.
Source: http://mp.weixin.qq.com/s/ZoJzF9VpynUBSQWlJJjmEw
Springboot video tutorial: http://www.roncoo.com/course/list.html? CourseName = spring + boot