-
搜索引擎服務(wù)使用ElasticSearch
-
提供的對外web服務(wù)選則springboot web
1.1 ElasticSearch
Elasticsearch是一個基于Lucene的搜索服務(wù)器。它提供了一個分布式多用戶能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java語言開發(fā)的,并作為Apache許可條款下的開放源碼發(fā)布,是一種流行的企業(yè)級搜索引擎。Elasticsearch用于云計算中,能夠達到實時搜索,穩(wěn)定,可靠,快速,安裝使用方便。
官方客戶端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和許多其他語言中都是可用的。根據(jù)DB-Engines的排名顯示,Elasticsearch是最受歡迎的企業(yè)搜索引擎,其次是Apache Solr,也是基于Lucene。1
現(xiàn)在開源的搜索引擎在市面上最常見的就是ElasticSearch和Solr,二者都是基于Lucene的實現(xiàn),其中ElasticSearch相對更加重量級,在分布式環(huán)境表現(xiàn)也更好,二者的選則需考慮具體的業(yè)務(wù)場景和數(shù)據(jù)量級。對于數(shù)據(jù)量不大的情況下,完全需要使用像Lucene這樣的搜索引擎服務(wù),通過關(guān)系型數(shù)據(jù)庫檢索即可。
1.2 springBoot
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”.2
現(xiàn)在springBoot在做web開發(fā)上是絕對的主流,其不僅僅是開發(fā)上的優(yōu)勢,在布署,運維各個方面都有著非常不錯的表現(xiàn),并且spring生態(tài)圈的影響力太大了,可以找到各種成熟的解決方案。
1.3 ik分詞器
elasticSearch本身不支持中文的分詞,需要安裝中文分詞插件,如果需要做中文的信息檢索,中文分詞是基礎(chǔ),此處選則了ik,下載好后放入elasticSearch的安裝位置的plugin目錄即可。
2 環(huán)境準(zhǔn)備
需要安裝好elastiSearch以及kibana(可選),并且需要lk分詞插件。
-
安裝elasticSearch elasticsearch官網(wǎng). 筆者使用的是7.5.1。
-
ik插件下載 ik插件github地址. 注意下載和你下載elasticsearch版本一樣的ik插件。
-
將ik插件放入elasticsearch安裝目錄下的plugins包下,新建報名ik,將下載好的插件解壓到該目錄下即可,啟動es的時候會自動加載該插件。
- 搭建springboot項目 idea ->new project ->spring initializer
3 項目架構(gòu)
-
獲取數(shù)據(jù)使用ik分詞插件
-
將數(shù)據(jù)存儲在es引擎中
-
通過es檢索方式對存儲的數(shù)據(jù)進行檢索
-
使用es的java客戶端提供外部服務(wù)
4 實現(xiàn)效果
4.1 搜索頁面
簡單實現(xiàn)一個類似百度的搜索框即可。
4.2 搜索結(jié)果頁面
點擊第一個搜索結(jié)果是我個人的某一篇博文,為了避免數(shù)據(jù)版權(quán)問題,筆者在es引擎中存放的全是個人的博客數(shù)據(jù)。
5 具體代碼實現(xiàn)
5.1 全文檢索的實現(xiàn)對象
按照博文的基本信息定義了如下實體類,主要需要知道每一個博文的url,通過檢索出來的文章具體查看要跳轉(zhuǎn)到該url。
package com.lbh.es.entity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.persistence.*;
/**
-
PUT articles
-
{
-
“mappings”:
-
{“properties”:{
-
“author”:{“type”:“text”},
-
“content”:{“type”:“text”,“analyzer”:“ik_max_word”,“search_analyzer”:“ik_smart”},
-
“title”:{“type”:“text”,“analyzer”:“ik_max_word”,“search_analyzer”:“ik_smart”},
-
“createDate”:{“type”:“date”,“format”:“yyyy-MM-dd HH:mm:ss||yyyy-MM-dd”},
-
“url”:{“type”:“text”}
-
} },
-
“settings”:{
-
"index":{
-
"number_of_shards":1,
-
"number_of_replicas":2
-
}
-
}
-
}
-
-
Copyright?lbhbinhao@163.com
-
@author liubinhao
-
@date 2021/3/3
*/
@Entity
@Table(name = “es_article”)
public class ArticleEntity {
@Id
@JsonIgnore
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = “author”)
private String author;
@Column(name = “content”,columnDefinition=“TEXT”)
private String content;
@Column(name = “title”)
private String title;
@Column(name = “createDate”)
private String createDate;
@Column(name = “url”)
private String url;
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getCreateDate() {
return createDate;
}
public void setCreateDate(String createDate) {
this.createDate = createDate;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
復(fù)制代碼
5.2 客戶端配置
通過java配置es的客戶端。
package com.lbh.es.config;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
/**
-
Copyright?lbhbinhao@163.com
-
@author liubinhao
-
@date 2021/3/3
*/
@Configuration
public class EsConfig {
@Value(“${elasticsearch.schema}”)
private String schema;
@Value(“${elasticsearch.address}”)
private String address;
@Value(“${elasticsearch.connectTimeout}”)
private int connectTimeout;
@Value(“${elasticsearch.socketTimeout}”)
private int socketTimeout;
@Value(“${elasticsearch.connectionRequestTimeout}”)
private int tryConnTimeout;
@Value(“${elasticsearch.maxConnectNum}”)
private int maxConnNum;
@Value(“${elasticsearch.maxConnectPerRoute}”)
private int maxConnectPerRoute;
@Bean
public RestHighLevelClient restHighLevelClient() {
// 拆分地址
List hostLists = new ArrayList<>();
String[] hostList = address.split(“,”);
for (String addr : hostList) {
String host = addr.split(“:”)[0];
String port = addr.split(“:”)[1];
hostLists.add(new HttpHost(host, Integer.parseInt(port), schema));
}
// 轉(zhuǎn)換成 HttpHost 數(shù)組
HttpHost[] httpHost = hostLists.toArray(new HttpHost[]{});
// 構(gòu)建連接對象
RestClientBuilder builder = RestClient.builder(httpHost);
// 異步連接延時配置
builder.setRequestConfigCallback(requestConfigBuilder -> {
requestConfigBuilder.setConnectTimeout(connectTimeout);
requestConfigBuilder.setSocketTimeout(socketTimeout);
requestConfigBuilder.setConnectionRequestTimeout(tryConnTimeout);
return requestConfigBuilder;
});
// 異步連接數(shù)配置
builder.setHttpClientConfigCallback(httpClientBuilder -> {
httpClientBuilder.setMaxConnTotal(maxConnNum);
httpClientBuilder.setMaxConnPerRoute(maxConnectPerRoute);
return httpClientBuilder;
});
return new RestHighLevelClient(builder);
}
}
復(fù)制代碼
5.3 業(yè)務(wù)代碼編寫
包括一些檢索文章的信息,可以從文章標(biāo)題,文章內(nèi)容以及作者信息這些維度來查看相關(guān)信息。
package com.lbh.es.service;
import com.google.gson.Gson;
import com.lbh.es.entity.ArticleEntity;
import com.lbh.es.repository.ArticleRepository;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
/**
-
Copyright?lbhbinhao@163.com
-
@author liubinhao
-
@date 2021/3/3
*/
@Service
public class ArticleService {
private static final String ARTICLE_INDEX = “article”;
@Resource
private RestHighLevelClient client;
@Resource
private ArticleRepository articleRepository;
public boolean createIndexOfArticle(){
Settings settings = Settings.builder()
.put(“index.number_of_shards”, 1)
.put(“index.number_of_replicas”, 1)
.build();
// {“properties”:{“author”:{“type”:“text”},
// “content”:{“type”:“text”,“analyzer”:“ik_max_word”,“search_analyzer”:“ik_smart”}
自我介紹一下,小編13年上海交大畢業(yè),曾經(jīng)在小公司待過,也去過華為、OPPO等大廠,18年進入阿里一直到現(xiàn)在。
深知大多數(shù)Java工程師,想要提升技能,往往是自己摸索成長或者是報班學(xué)習(xí),但對于培訓(xùn)機構(gòu)動則幾千的學(xué)費,著實壓力不小。自己不成體系的自學(xué)效果低效又漫長,而且極易碰到天花板技術(shù)停滯不前!
因此收集整理了一份《2024年Java開發(fā)全套學(xué)習(xí)資料》,初衷也很簡單,就是希望能夠幫助到想自學(xué)提升又不知道該從何學(xué)起的朋友,同時減輕大家的負(fù)擔(dān)。
既有適合小白學(xué)習(xí)的零基礎(chǔ)資料,也有適合3年以上經(jīng)驗的小伙伴深入學(xué)習(xí)提升的進階課程,基本涵蓋了95%以上Java開發(fā)知識點,真正體系化!
由于文件比較大,這里只是將部分目錄截圖出來,每個節(jié)點里面都包含大廠面經(jīng)、學(xué)習(xí)筆記、源碼講義、實戰(zhàn)項目、講解視頻,并且會持續(xù)更新!
如果你覺得這些內(nèi)容對你有幫助,可以掃碼獲取?。。▊渥ava獲取)

言盡于此,完結(jié)
無論是一個初級的 coder,高級的程序員,還是頂級的系統(tǒng)架構(gòu)師,應(yīng)該都有深刻的領(lǐng)會到設(shè)計模式的重要性。
- 第一,設(shè)計模式能讓專業(yè)人之間交流方便,如下:
程序員A:這里我用了XXX設(shè)計模式
程序員B:那我大致了解你程序的設(shè)計思路了
- 第二,易維護
項目經(jīng)理:今天客戶有這樣一個需求…
程序員:明白了,這里我使用了XXX設(shè)計模式,所以改起來很快
- 第三,設(shè)計模式是編程經(jīng)驗的總結(jié)
程序員A:B,你怎么想到要這樣去構(gòu)建你的代碼
程序員B:在我學(xué)習(xí)了XXX設(shè)計模式之后,好像自然而然就感覺這樣寫能避免一些問題
- 第四,學(xué)習(xí)設(shè)計模式并不是必須的
程序員A:B,你這段代碼使用的是XXX設(shè)計模式對嗎?
程序員B:不好意思,我沒有學(xué)習(xí)過設(shè)計模式,但是我的經(jīng)驗告訴我是這樣寫的
從設(shè)計思想解讀開源框架,一步一步到Spring、Spring5、SpringMVC、MyBatis等源碼解讀,我都已收集整理全套,篇幅有限,這塊只是詳細(xì)的解說了23種設(shè)計模式,整理的文件如下圖一覽無余!
搜集費時費力,能看到此處的都是真愛!
《一線大廠Java面試題解析+核心總結(jié)學(xué)習(xí)筆記+最新講解視頻+實戰(zhàn)項目源碼》,點擊傳送門即可獲??!
第一,設(shè)計模式能讓專業(yè)人之間交流方便,如下:
程序員A:這里我用了XXX設(shè)計模式
程序員B:那我大致了解你程序的設(shè)計思路了
- 第二,易維護
項目經(jīng)理:今天客戶有這樣一個需求…
程序員:明白了,這里我使用了XXX設(shè)計模式,所以改起來很快
- 第三,設(shè)計模式是編程經(jīng)驗的總結(jié)
程序員A:B,你怎么想到要這樣去構(gòu)建你的代碼
程序員B:在我學(xué)習(xí)了XXX設(shè)計模式之后,好像自然而然就感覺這樣寫能避免一些問題
- 第四,學(xué)習(xí)設(shè)計模式并不是必須的
程序員A:B,你這段代碼使用的是XXX設(shè)計模式對嗎?
程序員B:不好意思,我沒有學(xué)習(xí)過設(shè)計模式,但是我的經(jīng)驗告訴我是這樣寫的
[外鏈圖片轉(zhuǎn)存中…(img-nrz3GOnM-1711933868009)]
從設(shè)計思想解讀開源框架,一步一步到Spring、Spring5、SpringMVC、MyBatis等源碼解讀,我都已收集整理全套,篇幅有限,這塊只是詳細(xì)的解說了23種設(shè)計模式,整理的文件如下圖一覽無余!
[外鏈圖片轉(zhuǎn)存中…(img-Sah5EZMT-1711933868010)]文章來源:http://www.zghlxwxcb.cn/news/detail-859293.html
搜集費時費力,能看到此處的都是真愛!
《一線大廠Java面試題解析+核心總結(jié)學(xué)習(xí)筆記+最新講解視頻+實戰(zhàn)項目源碼》,點擊傳送門即可獲?。?/strong>文章來源地址http://www.zghlxwxcb.cn/news/detail-859293.html
到了這里,關(guān)于基于 ElasticSearch 實現(xiàn)站內(nèi)全文搜索,寫得太好了的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!