国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

《Spring Boot 實戰(zhàn)派》--13.集成NoSQL數(shù)據(jù)庫,實現(xiàn)Elasticsearch和Solr搜索引擎

這篇具有很好參考價值的文章主要介紹了《Spring Boot 實戰(zhàn)派》--13.集成NoSQL數(shù)據(jù)庫,實現(xiàn)Elasticsearch和Solr搜索引擎。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

第13章 集成NoSQL數(shù)據(jù)庫,實現(xiàn)Elasticsearch和Solr搜索引擎

?????????關(guān)于搜索引擎 我們很難實現(xiàn) Elasticseach 和 Solr兩大搜索框架的效果;所以本章針對兩大搜索框架,非常詳細(xì)地講解 它們的原理和具體使用方法,

首先 介紹什么是搜索引擎 、如何用 MySQL實現(xiàn)簡單的搜索引擎,以及Elasticseach 的 概念和接口類;

然后介紹Elasticseach 的精準(zhǔn)、模糊、范圍、組合、分頁、聚合查詢;

最后介紹 Solr的概念、安裝、配置和使用,并對兩大搜索框架進(jìn)行比較。

13.1?Elasticseach --- 搜索應(yīng)用服務(wù)器

13.1.1什么是搜索引擎

????????搜索引擎(search engine)通常意義上是指:根據(jù)特定策略,運用特定的爬蟲程序從互聯(lián)網(wǎng)?上搜集信息,然后對信息進(jìn)行處理后,為用戶提供檢索服務(wù),將檢索到的相關(guān)信息展示給用戶的系統(tǒng)。

本章主要講解的是搜索的索引和檢索,不涉及爬蟲程序的內(nèi)容爬取。大部分公司的業(yè)務(wù)也不會有爬取工作,而只提供查詢服務(wù),而且Elasticsearch也只是提供這方面的功能。

13.1.2用數(shù)據(jù)庫實現(xiàn)搜索功能

????????在極少量的數(shù)據(jù)應(yīng)用中,可以利用關(guān)系型數(shù)據(jù)庫的Select語句實現(xiàn)搜索功能。比如有一個電子?商務(wù)系統(tǒng),采用MySQL數(shù)據(jù)庫,其產(chǎn)品數(shù)據(jù)表如圖13-1所示。

《Spring Boot 實戰(zhàn)派》--13.集成NoSQL數(shù)據(jù)庫,實現(xiàn)Elasticsearch和Solr搜索引擎

需要實現(xiàn)產(chǎn)品搜索功能,可以使用如下SQL語句:

select * from product where 字段 like '%關(guān)鍵詞%'
select * from product where 字段 like '關(guān)鍵詞%'

  上述SQL語句中,如果要使用索引提高性能,則like就必須寫成like 'a%'或 '%a'形式。兩邊都加上“%”是不會觸發(fā)索引的。

我們先不考慮性能,只從商業(yè)效果上來看下面的演示是否能滿足用戶的需求。

1.簡單查詢

????????假如,用戶想搜索“紅富士”的蘋果,當(dāng)搜索關(guān)鍵詞“紅富士”之后,MySQL執(zhí)行SQL語句,?如圖13-2所示。

《Spring Boot 實戰(zhàn)派》--13.集成NoSQL數(shù)據(jù)庫,實現(xiàn)Elasticsearch和Solr搜索引擎

????????????????查詢結(jié)果是“name”字段中出現(xiàn)“紅富士”的產(chǎn)品信息。

2.多字段模糊查詢

????????上面已經(jīng)實現(xiàn)了簡單的查詢。但是,我們發(fā)現(xiàn)產(chǎn)品“金帥”的“body”字段中是"金帥,蘋果中一種好吃的蘋果,和紅富士一樣好吃”,這包含了 “紅富士”關(guān)鍵詞,如何才能把“body”字段?中的關(guān)鍵詞也搜索到呢?

????????現(xiàn)在對SQL語句進(jìn)行改進(jìn),改為如圖13-3所示的SQL語句。可以看到,"body"字段中有?“紅富士”的詞也被檢索出來了。

《Spring Boot 實戰(zhàn)派》--13.集成NoSQL數(shù)據(jù)庫,實現(xiàn)Elasticsearch和Solr搜索引擎

3.分詞查詢

????????由于用戶輸入時可能會存在輸入錯誤的情況,假設(shè)用戶輸入的是“紅富s”,那么數(shù)據(jù)庫是無法查詢到結(jié)果的。這時需要用分詞算法對輸入數(shù)據(jù)進(jìn)行分詞,可以分為:

紅、富、S

紅富、S

紅、富S

然后對詞進(jìn)行分別查詢,查詢結(jié)果如圖13-4所示。

《Spring Boot 實戰(zhàn)派》--13.集成NoSQL數(shù)據(jù)庫,實現(xiàn)Elasticsearch和Solr搜索引擎

????????我們會發(fā)現(xiàn)結(jié)果中把“name”和“body”字段都搜索出來了,但是出現(xiàn)了一個問題一蘋果XS?手機殼不該出現(xiàn)卻出現(xiàn)了。當(dāng)然這里排在最后,可能對用戶影響不大,但是如果加上排序字段,

根據(jù)最新添加來排序呢?則變成了如圖13-5所示的效果。

????????這就會影響用戶的搜索體驗,本意是查詢水果的,結(jié)果手機配件卻排在了第一位,問題在哪里?呢?其中一個原因就是分詞沒分好,然后沒有權(quán)重設(shè)置(權(quán)重這里暫時不涉及)。所以,此時需要一?個很好的分詞系統(tǒng)。

《Spring Boot 實戰(zhàn)派》--13.集成NoSQL數(shù)據(jù)庫,實現(xiàn)Elasticsearch和Solr搜索引擎

????????從MySQL 5.7開始內(nèi)置了?ngram全文檢索插件,用來支持中文分詞,并且對MylSAM和?InnoDB引擎有效。在使用中文檢索分詞插件ngram之前,需要在MySQL配置文件里面設(shè)置它的?分詞大小,比如設(shè)置為2:

ngram_token_size=2

然后可以使用match命令進(jìn)行查詢。

select * from product where match (name, body)? against? ('紅富?s');

分詞的結(jié)果就變成了:

紅富、富S、紅S

查詢結(jié)果如圖13-6所示。

《Spring Boot 實戰(zhàn)派》--13.集成NoSQL數(shù)據(jù)庫,實現(xiàn)Elasticsearch和Solr搜索引擎

????????乍一看效果很好,但實際并不太科學(xué),配置限定死了,沒法根據(jù)應(yīng)用環(huán)境來配置。比如搜索“蘋 果XR"這個手機,因為分詞長度為“2”,那么蘋果這種水果也會被搜索岀來,所以結(jié)果不盡如?人意。

????????通過以上實例可以看出,如果用MySQL等關(guān)系型或NoSQL數(shù)據(jù)庫去實現(xiàn)搜索引擎還是很麻?煩的,即使在不考慮性能的情況下,考慮的問題依然非常多。

????????如果加上性能因素來考量,即使對數(shù)?據(jù)庫進(jìn)行索引,在面對復(fù)雜情況下的查詢時,效果和性能都是不盡如人意的。

????????所以,在現(xiàn)在信息爆炸的時代,處理大規(guī)模數(shù)據(jù)就顯得力不從心,這時需要一種專業(yè)、配置簡?單、性能極優(yōu)的搜索引擎系統(tǒng),如果能開源、可實現(xiàn)分布式、支持RESTfulAPI,則學(xué)習(xí)、使用成?本、性能和實

現(xiàn)就非常完美了。這時,Elasticsearch和Solr就出現(xiàn)在我們面前了。

13.1.3?認(rèn)識?Elasticsearch

????????Elasticsearch是一個分布式、RESTful風(fēng)格的搜索和數(shù)據(jù)分析引擎。通過它,能夠執(zhí)行及合并多種類型的搜索(結(jié)構(gòu)化數(shù)據(jù)、非結(jié)構(gòu)化數(shù)據(jù)、地理位置、指標(biāo)),解決不斷涌現(xiàn)出的各種需求。

????????Elasticsearch使用的是標(biāo)準(zhǔn)的RESTful風(fēng)格的API,使用JSON提供多種語言(Java、?Python、Net、SQL和PHP)的支持,它可以快速地存儲、搜索和分析海量數(shù)據(jù)。

????????Elasticsearch是用Java語言開發(fā)的,并使用Lucene作為其核心來實現(xiàn)所有索引和搜索的功?能。它的目的是:通過簡單的RESTful API來隱藏Lucene的復(fù)雜性,從而讓全文搜索變得簡單。

????????Elasticsearch是一個幵源的高擴展的分布式全文檢索引擎,可以近乎實時地存儲、檢索數(shù)據(jù);?本身擴展性很好,允許多臺服務(wù)器協(xié)同工作,每臺服務(wù)器可以運行多個實例。單個實例稱為一個節(jié)?點(node),—組節(jié)點構(gòu)成一個集群(cluster)?分片是底層的工作單元,文檔保存在分片內(nèi),分片?又被分配到集群內(nèi)的各個節(jié)點里,每個分片僅保存全部數(shù)據(jù)的一部分。

????????當(dāng)Elasticsearch的節(jié)點啟動后,它會使用多播(multicast)或單播(用戶更改了配置)尋找?集群中的其他節(jié)點,并與之建立連接。

13.1.4?Elasticsearch 應(yīng)用案例

  • GitHub: 2013年年初,GitHub把Solr緩存改成了?Elasticsearch,以便用戶搜索20TB 的數(shù)據(jù),包括13億個文件和1300億行代碼。
  • 維基百科:啟動以Elasticsearch為基礎(chǔ)的核心搜索架構(gòu)SoundCloud,為1.8億用戶提供?即時而精準(zhǔn)的音樂搜索服務(wù)。
  • 百度:百度使用Elasticsearch作為數(shù)據(jù)分析引擎,20多個業(yè)務(wù)線采集服務(wù)器上的各類數(shù)?據(jù)及用戶自定義數(shù)據(jù),通過對各種數(shù)據(jù)進(jìn)行多維分析,輔助定位異常。其單集群最大100臺?機器,200個Elasticsearch節(jié)點,每天導(dǎo)入超過30TB的數(shù)據(jù)。

除這些公司外,Stack Overflow.新浪、阿里、360、攜程、有贊、蘇寧都在使用它。它被廣泛地用于各大公司的站內(nèi)搜索、IT系統(tǒng)搜索(OA、CRM、ERP)、數(shù)據(jù)分析等工作中。

13.1.5?對比?Elasticsearch?與?MySQL

????????盡管將Elasticsearch與MySQL進(jìn)行對比并不科學(xué),但是這樣的對比能區(qū)分日asticsearch 和MySQL數(shù)據(jù)庫的區(qū)別,便于快速用熟悉的知識來理解Elasticsearcho所以,本節(jié)采用對比的

方式來講解Elasticsearch。Elasticsearch與MySQL的結(jié)構(gòu)對比見表13-1。

表?13-1 Elasticsearch?與?MySQL 的結(jié)構(gòu)對比

ElasticSearch

MySQL

ElasticSearch

MySQL

index

database

everything is indexed

index

type

table

query dsl

sql

document

row

get url

select *from table

field

column

put url

update table set

mapping

schema

(1)關(guān)系型數(shù)據(jù)庫中的數(shù)據(jù)庫,相當(dāng)于Elasticsearch中的索引(index )

(2)?—個數(shù)據(jù)庫下面有多張表(table),相當(dāng)于一個索引(index)下面有多個類型(type)。

(3)?—個數(shù)據(jù)庫表(table)下的數(shù)據(jù)由多行(row)多列(column,屬性)組成,相當(dāng)于一個?type由多個文檔(document)和多個field組成。

(4)?在關(guān)系型數(shù)據(jù)庫中,schema定義了表、每個表的字段,還有表和字段之間的關(guān)系;? ? ?在?Elasticsearch中,mapping定義索引下的type的字段處理規(guī)則,即索引如何建立、索引類型、?是否保存原始索引JSON文檔、是否壓縮原始JSON文檔、是否需要分詞處理、如何進(jìn)行分詞處?理等。

(5)?在?MySQL?數(shù)據(jù)庫中的增(insert )、刪(delete )、改(update )、查(select)操作相當(dāng)于?Elasticsearch 中的增(put/post )、刪(delete )、改(update)、查(get)。

????????客戶端主要通過“方法(PUT/POST/GET/DELETE ) + http://ip:端口/索引名稱/類型/主鍵” 來訪問內(nèi)容。

13.1.6?認(rèn)識?ElasticSearchRepository

????????Spring-data-elasticsearch?是?Spring?提供的操作?Elasticsearch 的數(shù)據(jù)接口,它封裝了大量的基礎(chǔ)操作,通過它可以很方便地操作Elasticsearch的數(shù)據(jù)。

????????通過繼承ElasticsearchRepository來完成基本的CRUD及分頁操作,和普通的JPA沒有什么區(qū)別。比如下面實體Product的Repository繼承ElasticsearchRepository后,可以在?Elasticsearch文檔中進(jìn)行查找和比較等操作。具體使用方法見以下代碼:

?Component
public interface ProductRepository extends ElasticsearchRepository<Product,Long> {
    Product findByld(long id);
    Product findByName(String name);
    List<Product> findByPriceBetween(double price 1, double price2);
}

  

????????ElasticsearchRepository有幾個特有的search方法,用來構(gòu)建一些Elasticsearch查詢,?主要由QueryBuilder 和 SearchQuery兩個參數(shù)來完成一些特殊查詢。

????????實現(xiàn)類NativeSearchQuery實現(xiàn)了?QueryBuilder和SearchQuery方法,要構(gòu)建復(fù)雜查詢,?可以通過構(gòu)建NativeSearchQuery類來實現(xiàn)。

????????—般情況下,不是直接新建NativeSearchQuery類,而是使用NativeSearchQueryBuilder 來完成NativeSearchQuery的構(gòu)建。具體用法見以下代碼:

NativeSearchQueryBuilder
.withQuery(QueryBuilder1)
.withFilter(QueryBuilder2) 
.withSort(SortBuilder1) 
.withXxx().build()

  

13.1.7?認(rèn)識?ElasticsearchTemplate

????????ElasticsearchTemplate是Spring對Elasticsearch的API進(jìn)行的封裝,主要用來對索引進(jìn)行倉U建、刪除等操作。它繼承了?Elasticsearchdperations?和?ApplicationContextAware?接口。?ElasticSearchTemplate?提供一些比?ElasticsearchRepository 更底層的方法。

ElasticsearchOperations接口中常用的方法如下。

  • createlndex()方法:創(chuàng)建索引,返回值為布爾類型數(shù)據(jù)。
  • indexExists()方法:查詢索引是否存在,返回值為布爾類型數(shù)據(jù)。
  • putMapping()方法:創(chuàng)建映射,返回值為布爾類型數(shù)據(jù)。
  • getMapping()方法:得到映射,返回值為一個Map數(shù)據(jù)。
  • deletelndex()方法:刪除索引,返回值為布爾類型數(shù)據(jù)。

13.1.8?認(rèn)識注解@Document

????????注解@Document作用于類,用于標(biāo)記實體類為文檔對象。

存儲在Elasticsearch中的一條數(shù)據(jù),即是一個文檔,類似關(guān)系型數(shù)據(jù)庫的一行數(shù)據(jù)。?Elasticsearch會索引每個文檔的內(nèi)容,以便搜索。它使用JSON格式,將數(shù)據(jù)存儲到Elasticsearch 中,實際上是將JSON格式的字符串發(fā)送給了?Elasticsearch。

1.、document的核心元數(shù)據(jù)

document有三個核心元數(shù)據(jù),分別是_index、_type、_id。

(1) _index;代表一個document存放在哪個index中,類似的數(shù)據(jù)放在一個索引中,非類似的數(shù)據(jù)放在不同的索引中。index中包含了很多類似的document,這些document的field很大一部分是相同的。索引名稱必須小寫,不能用下畫線開頭,不包含逗號。

(2) _type;代表document屬于index的哪個類別,一個索引通常會劃分為多個type,邏輯?上對index不同的數(shù)據(jù)進(jìn)行分類。type名稱可以是大寫或小寫,但是不能用下畫線開頭,不能包含?逗號。

(3 ) _id;代表document的唯一標(biāo)識,與Jndex和_type —起可以標(biāo)識和定位一個 documento默認(rèn)自動創(chuàng)建id,也可以手動指定document的id。

2、document id的手動指定和自動生成

(1)手動指定document id。

????????如果需要從某些其他系統(tǒng)中導(dǎo)入一些數(shù)據(jù)到Elasticsearch,則會采用手動指定id的形式,因為一般情況下系統(tǒng)中已有數(shù)據(jù)的唯一標(biāo)識,可以用作Elasticsearch中的document的id

其語法格式為:

put /index/type/id
{
    "json"
}
(2)自動生成 document id。
其語法格式為:

post /index/type
{
    "json"
}

  自動生成的id長度為20個字符,URL安全、Base64編碼、GUID、分布式系統(tǒng)并行生成時不會發(fā)生沖突。

3、document_source元數(shù)據(jù),以及定制返回結(jié)果

????????_source元數(shù)據(jù)是在創(chuàng)建document時放在body中的JSON數(shù)據(jù)。在默認(rèn)情況下,查找數(shù)據(jù)?時會返回全部數(shù)據(jù)。如果要定制返回結(jié)果,則可以指定_source中返回哪些field

例如:

GET /_index/_type/1?_source=field

  

13.1.9 管理索引

1、創(chuàng)建索引

(1)?根據(jù)類的信息自動生成創(chuàng)建索引。

????????下面代碼是根據(jù)實體類創(chuàng)建一個名為“ec”的索引,并定義tpye是“product”。由于是單機環(huán)境,所以定義副本為0,分片為默認(rèn)值5。

@Document(indexName = "product", type = "product", replicas = 0, shards = 5)
public class Product implements Serializable {
)

 代碼解釋如下。

  • indexName :對應(yīng)索引庫名稱,可以理解為數(shù)據(jù)庫名。必須小寫,否則會報 "org.elasticsearch.indices.InvalidlndexNameException"異常。
  • type:對應(yīng)在索引庫中的類型,可以將其理解為“表名”。
  • shards:分片數(shù)量,默認(rèn)值為5。
  • replicas:副本數(shù)量,默認(rèn)值為1。如果是單機環(huán)境,則健康狀態(tài)為“yellow”。如果要成為?“green”,則指定值為0即可。

(2)?手動創(chuàng)建索引。

? ? 可以使用createlndex方法手動指定indexName和Settings,再進(jìn)行映射。在使用前,要先注入ElasticsearchTemplate。使用方法如下。

  • 根據(jù)索引名創(chuàng)建索引:lasticsearchTemplate.create!ndex("indexname");
  • 根據(jù)類名創(chuàng)建索引:lasticsearchTemplate.createlndex(Product.class);

2、查詢索引

  • 根據(jù)索引名查詢:elasticsearchTemplate.indexExists("indexname");
  • 根據(jù)類名查詢:elasticsearchTemplate.indexExists(Product.class);

3、刪除索引

? 可以根據(jù)索引名和類名對索引進(jìn)行刪除。

  • 根據(jù)索引名刪除:elasticsearchTemplate.deletelndex("indexname");
  • 根據(jù)類名刪除:elasticsearchTemplate.deletelndex(Product.class);

13.2?實例55:用ELK管理Spring Boot應(yīng)用程序的日志

????????ELK?是?Elasticsearch+Logstash+Kibana 的簡稱。

????????Logstash負(fù)責(zé)將數(shù)據(jù)信息從輸入端傳輸?shù)捷敵龆?,比如將信息從MySQL傳入Elasticsearch, 還可以根據(jù)自己的需求在中間加上濾網(wǎng)。Logstash提供了很多功能強大的濾網(wǎng),以滿足各種應(yīng)?用場景。

Logstash有以下兩種工作方式:

(1) 每一臺機器啟動一個Logstash服務(wù),讀取本地的數(shù)據(jù)文件,生成流傳給Elasticsearch

(2) Logback引入Logstash包,然后直接生產(chǎn)JSON流,傳給一個中心的Logstash服務(wù)?器,Logstash?服務(wù)器再傳給?Elasticsearch。最后,Elasticsearch?將其流傳給?Kibana。

????????Kibana是一個開源的分析與可視化平臺,和Elasticsearch —起使用??梢杂?strong>Kibana搜索、?查看、交互存放在日asticsearch索弓I里的數(shù)據(jù)。使用各種不同的圖標(biāo)、表格、地圖等,Kibana能夠很輕易地展示高級數(shù)據(jù)分析與可視化。

????????ELK架構(gòu)為數(shù)據(jù)分布式存儲、日志解析和可視化創(chuàng)建了一個功能強大的管理鏈。三者相互配合,?取長補短,共同完成分布式大數(shù)據(jù)處理工作。

本實例通過Logstash收集本地的log文件流,傳輸給Elasticsearch。

本實例的源代碼可以在“/13/ELKDemo”目錄下找到。

13.2.1?安裝?Elasticsearch

(1)?通過官網(wǎng)下載Elasticsearch?

(2)?在下載完成后,首先將其解壓到合適的目錄,然后進(jìn)入解壓目錄下的bin目錄,雙擊?elasticsearch.bat文件啟動Elasticsearch。這里需要確保安裝的Java版本在1.8及以上。

(3)?訪問“http://127.0.0.1:9200/”,當(dāng)看到返回如下一串JSON格式的代碼時,則說明已經(jīng)?安裝成功了。

{
"name": "1q71xef",
"cluster_name": "elasticsearch",
//省略
"tagline": "You Know, for Search"
}

  根據(jù)應(yīng)用需要,還可以安裝Elasticsearch必要的一些插件,如Head、kibana、IK (中文分 詞)、graph

????????在Elasticsearch 6.0.0或更新版本中,創(chuàng)建的索引只會包含一個映射類型(mapping type ) ;

在Elasticsearch 5.x中創(chuàng)建的具有多個映射類型的索引在Elasticsearch 6.x中依然會正常工作。

在Elasticsearch 7.0.0 中,映射類型被完全移除了。

13.2.2?安裝?Logstash

1、安裝?Logstash

(1)?訪問?Elasticsearch?官網(wǎng)下載?Logstash?

(2)?將下載文件解壓到自定義的目錄即可。

2、配置?Logstash

(1)在解壓文件的config目錄下新建Iog4j_to_es.conf文件,寫入以下代碼:

input{
    tcp{
        host =>"localhost"
        port =>9601
        mode =>"server"
        tags =>["tags"]
##JSON格式
    codec => jsonjines
    }
}

output{
    elasticsearch{
        hosts=>"127.0.0.1:9200"
        index =>"demolog"
    }
    stdout{ codec=>rubydebug }
}

????????這里一定要注意:這是UTF-8的格式,不要帶BOM。如果啟動時岀現(xiàn)錯誤,則可以用“l(fā)ogstash -f ../config/xxx.conf -tn命令檢查配置文件是否錯誤。

(2)?新建文件run.bato?寫入代碼?“l(fā)ogstash -f ../config/log4j_to_es.conf”,保存。然后雙擊該配置文件,啟動Logstash

(3)?訪問“l(fā)ocalhost:9600”,如出現(xiàn)以下內(nèi)容,則代表配置成功。

{"host"":"zhonghua","version":"6.5.0","http_address":"127.0.0.1:9600","id":"03472165-2b17-4e5f-a1a1-f4 8ea4deb9a1","name":"zhonghua","build_date":"2018-11-09T19:43:40+00:00","build_sha":"4b3a404d6751 261 d155458c1 a8454a22167b1954","build_snapshot":false}

  

13.2.2?安裝?Kibana

????????Kibana是官方推出的Elasticsearch數(shù)據(jù)可視化工具。

(1 )通過訪問Elasticsearch官網(wǎng)下載Kibana。

(2)?解壓下載的壓縮文件,進(jìn)入解壓目錄,雙擊Kibana目錄的bin/kibana.bat,以啟動?Kibana,當(dāng)出現(xiàn)以下提示時,代表啟動成功。

? ? ? ?log? [08:23:47.611] [info][status][plugin:spaces@6.5.0] Status changed from yellow to green - Ready

(3)?訪問localhost:5601就可以進(jìn)入Kibana控制臺。

????????單擊控制臺左邊導(dǎo)航欄的“Dev-tools”按鈕,可以進(jìn)入Dev-tools界面。單擊“Get to work“, 然后在控制臺輸入“GET/_cat/health?”命令,可以查看服務(wù)器狀態(tài)。如果在右側(cè)返回的結(jié)果中看到green或yellow ,則表示服務(wù)器狀態(tài)正常。

????????yellow表示所有主分片可用,但不是所有副本分片都可用。如果Elasticsearch只是安裝在本地,且設(shè)置了副本大于0,則會出現(xiàn)黃色,這是正常的狀態(tài)。因為并沒有分布式部署,是單節(jié)點。另外,由于Elasticsearch默認(rèn)有1個副本,主分片和副本不能在同一個節(jié)點上,因此副本就是未分配(unassigned )

所以,在設(shè)計實體時可以設(shè)置@Document(indexName= "goods",type = "goods",shards = 5, yreplicas = 0),即?“repIicas=0”?就會變成?green;

13.2.4?配置?Spring Boot 項目

(1)添加項目依賴,見以下代碼:

<dependency>
    <groupld>org.springframework.boot</groupld> 
    <artifactld>spring-boot-starter-log4j</artifactld> 
    <version>1.3.8.RELEASE</version>
</dependency>
<dependency>
    <groupld>net.logstash.logback</groupld>
    <artifactld>logstash-logback-encoder</artifactld>
    <version>5.3</version>
</dependency>

 

(2)添加配置文件logback.xml,這里在Spring Boot項目里添加一個配置文件,見以下代碼:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="LOGSTASH"
            class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <destination>localhost:9601</destination>
        <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder" />
    </appender>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!--encoder必須配置,有多種可選字符集 -->
        <encoder charset="UTF-8">
            <pattern>%d{HH:mm:ss.SSS} [%thread]%-5level %logger - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="INFO">
        <appender-ref ref="LOGSTASH" />
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

 

13.2.5創(chuàng)建日志計劃任務(wù)

????????在Spring Boot項目中創(chuàng)建logTest類,用于測試將日志通過Logstash發(fā)送到日asticsearch, 見以下代碼

?Component
public class logTest {

    private Logger logger = LoggerFactory.getLogger(logTest.class);

    @Scheduled(fixedRate = 1000)
    public void logtest() {

        logger.trace("trace 日志");
        logger.debug("debug 日志");
        logger.info("info 日志");
        logger.warn("warn 日志");
        logger.error("error 日志");
    }
}

  

(1)在入口類中添加注解@EnableScheduling,開啟計劃任務(wù),然后運行項目。

(2 )訪問http://localhost:5601?

????????選擇左側(cè)導(dǎo)航欄的“Management —>Index Patterns —> Create index pattern"命令,輸?入"demolog",單擊"Next”按鈕,選擇時間過濾器字段名,單擊“Create index pattern”按鈕, 創(chuàng)建完成。

????????進(jìn)入Kibana的Discover,就可以查看日志信息了。

13.2.6用Kibana查看管理日志

????????在Kibana的Discover頁面中,可以交互式地探索自己的數(shù)據(jù)。這里可以訪問與所選擇的索引?默認(rèn)匹配的每個索引中的文檔,可以提交查詢請求、過濾搜索結(jié)構(gòu),并查看文檔數(shù)據(jù),

????????還可以看到?匹配查詢請求的文檔數(shù)量,以及字段值統(tǒng)計信息。

????????如果選擇的索引模式配置了?time字段,則文檔隨時間的分布將顯示在頁面頂部的直方圖中。?Discover

《Spring Boot 實戰(zhàn)派》--13.集成NoSQL數(shù)據(jù)庫,實現(xiàn)Elasticsearch和Solr搜索引擎

????????Kibana的功能非常強大,還可以進(jìn)行可視化設(shè)計,創(chuàng)建熱點圖、區(qū)域圖、餅圖、時間線等,也?可以監(jiān)控Elasticsearch的健康狀態(tài)。如果安裝了?APM支持,還可以進(jìn)行性能監(jiān)控。

13.3?實例?56:在?Spring Boot?中集成?Elasticsearch,實現(xiàn)增加、?刪除、修改、查詢文檔的功能

????????本實例講解如何在Spring Boot中實現(xiàn)增加、刪除、修改、查詢文檔的功能,以理解Spring Boot 的相關(guān)Starter的使用和Elasticsea「ch的知識點和具體應(yīng)用。

本實例的源代碼可以在"/13/ElasticsearchProductDemo”目錄下找到。

13.3.1?集成?Elasticsearch

????????Spring Boot?提?供?了?Starter ( spring-boot-starter-data-elasticsearch )?來集成?Elasticsearch?

  • 優(yōu)點:開發(fā)速度快,不要求熟悉Elasticsearch的一些API,能快速上手。即使之前對?Elasticsearch不了解,也能通過方法名或SQL語句快速寫出自己需要的邏輯。而具體轉(zhuǎn)換成API層的操作則是由框架底層實現(xiàn)的。
  • 缺點:使用的Spring Boot的版本對Elasticsearch的版本也有了要求,不能超過某些版本號,在部署時需要注意。如果采用API方式,則能解決這個問題。

(1 )添加依賴,見以下代碼:

<!--Elasticsearch 支持-->
<dependency>
  <groupld>org.springframework.boot</groupld> 
  <artifactld>spring-boot-starter-data-elasticsearch</artifactld> 
</dependency>

  

(2)添加application.properties配置?見以下代碼:

spring.data.elasticsearch.cluster-name=elasticsearch
#節(jié)點的地址。注意,API模式下端口號是9300,千萬不要寫成9200 
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300
#是否開啟本地存儲
spring.data.elasticsearch.repositories.enable=true

  

13.3.2創(chuàng)建實體

(1)創(chuàng)建實體。

這里根據(jù)類的信息自動生成,也可以手動指定索引名稱。ElasticsearchTemplate中提供了創(chuàng)?建索引的API,因為進(jìn)行本機測試,沒做集群,所以replicas副本先設(shè)置為0。見以下代碼:

//省略
//索引名稱可以理解為數(shù)據(jù)庫名,必須為小寫,否則會報"org.elasticsearch.indices.lnvalidlndexNameException" 異常
@Document(indexName = "ec", type = "product", replicas = 0, shards = 5)
//type (類型)可以理解為表名
@Data
public class Product implements Serializable {

    /**
     * Description: @ld 注解必須是 springframework 包下的
          org.springframework.data.annotation.Id
     /
    private Long id;

    @Field(type = FieldType.Text, analyzer ="ik_max_word")//ik_max_word 使用IK分詞器
    private String name;

    @Field(type = FieldType.Keyword)//在存儲數(shù)據(jù)時,不會對category進(jìn)行分詞
    //分類
    private String category;

    //價格
    @Field(type = FieldType.Double)
    private Double price;

    @Field(index = false, type = FieldType.Keyword)// index=false,表示不建立索引
    //圖片地址
    private String images;

    private String body;
}
//省略

 代碼解釋如下。

  • @ld注解:作用于成員變量,標(biāo)記一個字段作為id主鍵。
  • @Field注解:作用于成員變量,標(biāo)記為文檔的字段,需要指定字段映射屬性type。
  • index:是否索引,布爾類型,默認(rèn)為true。
  • store:是否存儲,布爾類型,默認(rèn)為false。
  • analyzer:分詞器名稱,這里的ik_max_word即使用IK分詞器。

(2)創(chuàng)建數(shù)據(jù)操作接口。

????????繼承ElasticsearchRepository即可創(chuàng)建數(shù)據(jù)操作接口,這樣不用寫方法,就具備了

Elasticsearch文檔的增加、刪除、修改和查詢功能。見以下代碼:

package com.example.demo.repository;
//省略
@Component
public interface ProductRepository extends ElasticsearchRepository<Product,Long> {

    Product findByld(long id);
    Product findByName(String name);
}

  

13.3.3實現(xiàn)增加、刪除、修改和查詢文檔的功能

在測試類中,實現(xiàn)對Elasticsearch文檔進(jìn)行增加、刪除、修改和查詢的功能,見以下代碼:

//省略
@SpringBootTest
@RunWith(SpringRunner.class)
public class ProductControllerTest {

    //每頁數(shù)量
    private Integer PAGESIZE=10;

    @Autowired
    private ProductRepository productRepository;

    @Test
    public void save() {
        long id= System.currentTimeMillis();
        Product product = new Product(id,
            "紅富士","水菓", 7.99, "/img/p1.jpg", "這是一個測試商品");
        productRepository.save(product); 
        System.out.println(product.getld());
    }

    @Test
    public void getProduct() {
        Product product = productRepository.findByName("紅富士");                            
        System.out.println(product.getld()); 
    }

    @Test
    public void update() {

        long id=1557032203515L;
        Product product = new Product(id,
                   "金帥水果", 7.99, "/img/p1.jpg", "金帥也和紅富士一樣,非常好吃,脆脆的");
        productRepository.save(product);
    }

    @Test
    public void getProductByld() {
        Product product = productRepository.findByld(1557032203515L);                 
        System.out.println(product.getName()+product.getBody());
    }

    @Test
    public void delete() {
        long id=1557032203515L;
        productRepository.deleteByld(id);
    }

    @Test
    public void getAll() {
        lterable<Product> list = productRepository.findAll(Sort.by("id").ascending());
        for (Product product: list) {
            System.out.println(product);
        }
    }
}

  請根據(jù)自己測試“save”方法返的id值進(jìn)行測試。這里的id值(1557032203515L ) 是筆者本機上得到的,讀者不能用這個id值進(jìn)行測試。

啟動項目,運行測試getAII,控制臺返回如下值:

Product(id=1557031659306, name=紅富士,category二水果 price=7.99, images=/img/p1.jpg, body二這是一個 測試商品)
Product(id=1557032088459, name二金帥,category=水果,price二7.99, images=/img/p1.jpg, body=金帥也和紅 富士一樣,非常好吃,脆脆的)
Product(id=1557032203515, name=紅富士,category=水果 price=7.99, images=/img/p1 .jpg, body二這是一個 測試商品)
Product(id=1557034189287, name=紅富士,category二水果,price=7.99, images=/img/p1.jpg, body=這是一個 測試商品)

  

13.4 Elasticsearch?查詢

????????可以根據(jù)Spring Data提供的方法名稱,實現(xiàn)自己想自定義的查詢功能:無須寫實現(xiàn)類,只要?繼承ElasticsearchRepository接口即可。

如“findByTitle”表示根據(jù)“title”進(jìn)行查詢,具體方?法見表

關(guān)鍵詞

例 子

And

findByNameAndPrice

Or

findByNameOrPrice

Is

findByName

Not

findByNameNot

Between

findByPriceBetween

關(guān)鍵詞

例 子

LessThanEqual

findByPriceLessThan

GreaterThanEqual

findByPriceGreaterThan

Before

findByPriceBefore

After

findByPriceAfter

Like

findByNameLike

StartingWith

findByNameStartingWith

EndingWith

findByNameEndingWith

Contains/Containing

findByNameContaining

In

findByNameln(Collection<String>names)

Notln

findByNameNotln(Collection<String>names)

Near

findByStoreNear

TRUE

findByAvailableT rue

FALSE

findByAvailableFalse

OrderBy

findByAvailableTrueOrderByNameDesc

如果要查詢價格在7?8元的商品,貝!J可以在接口類加上“List〈P「oduct> findByFYiceBetween (double pricel, double price2); ” 方法,見以下代碼:

@Component

public interface ProductRepository extends ElasticsearchRepository<Product,Long> { Product findByld(long id);

????????Product findByName(String name);

????????List<Product> findByPriceBetween(double pricel, double price2);

}

????????然后,在測試類中直接使用自定義的“findByP「iceBetween”方法查詢出數(shù)據(jù),見以下代碼:

@Test
public void queryByPriceBetween() {
    Iterable<Product> list = productRepository.findByPriceBetween(7.00, 8.00); 
    for (Product product: list) {
        System.out.println(product);
    }
}
其他的使用方法以此類推。

13.4.2精準(zhǔn)查詢

1、單參數(shù) termQuery

用法見以下代碼:

QueryBuilder queryBuilder = QueryBuilders.termQuery("字段名","查詢值");

  它是不分詞查詢。因為不分詞,所以漢字只能查詢一個字,而多字母的英語單詞算一個字。

具體實現(xiàn)見以下代碼:

@Test
public void termQuery(){
    //構(gòu)建查詢條件
    NativeSearchQueryBuilder nativeSearchQueryBuilderQueryBuilder = new         NativeSearchQueryBuilder();
    //查詢詞,只能查詢一個漢字,或一個英文單詞     nativeSearchQueryBuilderQueryBuilder.withQuery(QueryBuilders.termQuery("name","富"));
//搜索,獲取結(jié)果
Page<Product> products = productRepository.search(nativeSearchQueryBuilderQueryBuilder.build());
    //總條數(shù)
    for (Product product: products) {
        System.out.println(product);
    }
}

  

2、多參數(shù)? ?termsQuery

????????terms可以提供n個查詢的參數(shù)對一個字段進(jìn)行查詢,用法見以下代碼。注意,這里是term的復(fù)數(shù)形式terms?

QueryBuilder queryBuilder=QueryBuilders.termsQuery("字段名","查詢值", "查詢值")

  

具體實現(xiàn)見以下代碼:

@Test
//多參數(shù) termsQuery
public void termsQuery() {
    //構(gòu)建查詢條件
    NativeSearchQueryBuilder nativeSearchQueryBuilderQueryBuilder = new     NativeSearchQueryBuilder(); //查詢詞,只能查詢一個漢字或一個英文單詞
        nativeSearchQueryBuilderQueryBuilder.withQuery(QueryBuilders.termsQuery("name",'富',"帥"));         
    //搜索,獲取結(jié)果
    Page<Product> products = productRepository.search(nativeSearchQueryBuilderQueryBuilder.build());
    //總條數(shù)
    for (Product product: products) {
        System.out.println(product);
    }
}

  

3、分詞查詢? ?matchQuery

分詞查詢采用默認(rèn)的分詞器,用法見以下代碼:

QueryBuilder queryBuilder2 = QueryBuilders.matchQuery("字段名","查詢值");

  具體實現(xiàn)見以下代碼:

@Test
//分詞查詢采用默認(rèn)的分詞器
public void matchQuery() {
    //查詢條件
    NativeSearchQueryBuilder nativeSearchQueryBuilderQueryBuilder = new NativeSearchQueryBuilder();
    //查詢詞     
    nativeSearchQueryBuilderQueryBuilder.withQuery(QueryBuilders.matchQuery("name","紅士"));
    //搜索,獲取結(jié)果
    Page<Product> products= productRepository.search(nativeSearchQueryBuilderQueryBuilder.build()); 
    for (Product product: products) {
        System.out.println(product);
    }
}

  

4、 多字段查詢 multiMatchQuery

多字段查詢采用multiMatchQuery方法,用法見以下代碼:

QueryBuilder queryBuilder= QueryBuilders.multiMatchQuery("查詢值","字段名","字段名","字段名");

  

具體實現(xiàn)見以下代碼:

@Test
//多字段查詢
public void multiMatchQuery() {
    //構(gòu)建查詢條件
    NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();     
    nativeSearchQueryBuilder.withQuery(QueryBuilders.multiMatchQuery("紅富士金帥","name", "body")); 
    //搜索,獲取結(jié)果
    Page<Product> products = productRepository.search(nativeSearchQueryBuilder.build());
    //總條數(shù)
    for (Product product: products) {
        System.out.println(product);
    }
}

  

13.4.3模糊查詢

常見的模糊查詢的方法有4種。

1.左右模糊

用法見以下代碼:

QiteryBuilders.queryStringQuery("查詢值").field("字段名");

  

具體實現(xiàn)見以下代碼:

@Test
public void queryStringQuery() {
    //查詢條件
    NativeSearchQueryBuilder nativeSearchQueryBuilderQueryBuilder = new NativeSearchQueryBuilder();
    //左右模糊         
    nativeSearchQueryBuilderQueryBuilder.withQuery(QueryBuilders.queryStringQuery("我覚得紅富士好吃").field("name"));
    //搜索,獲取結(jié)果
    Page<Product> products= productRepository.search(nativeSearchQueryBuilderQueryBuilder.build()); 
    for (Product product: products) {
        System.out.println(product);
    }
}

  

2、前綴查詢? prefixQuery

????????如果字段沒分詞,則匹配整個字段前綴,用法見以下代碼:

QueryBuilders.prefixQuery("字段名","查詢值");

具體實現(xiàn)見以下代碼:

@Test
public void prefixQuery() {
    //查詢條件
    NativeSearchQueryBuilder nativeSearchQueryBuilderQueryBuilder = new NativeSearchQueryBuilder();
    //左右模糊
    ativeSearchQueryBuilderQueryBuilder.withQuery(QueryBuilders.prefixQuery("name","士"));
    //搜索,獲取結(jié)果
    Page<Product> products= productRepository.search(nativeSearchQueryBuilderQueryBuilder.build());
    for (Product product: products) {
        System.out.println(product);
    }
}

  

3、通配符查詢 wildcard query

????????使用通配符方式進(jìn)行查詢,支持通配符“*”和“?”?!?”代表任意字符串,“?”代表任意一?個字符。

(1) 使用通配符 “*”。

????????通配符“*”可以匹配多個值,用法見以下代碼:

QueryBuilders.wildcardQuery("字段名", "查詢值*");

  具體實現(xiàn)見以下代碼:

@Test
public void wildcardQuery() {
    //查詢條件
    NativeSearchQueryBuilder nativeSearchQueryBuilderQueryBuilder = new NativeSearchQueryBuilder();
    nativeSearchQueryBuilderQueryBuilder.withQuery(QueryBuilders.wildcardQuery("name","金*"));
    //搜索,獲取結(jié)果
    Page<Product> products = productRepository.search(nativeSearchQueryBuilderQueryBuilder.build()); 
    for (Product product: products) {
        System.out.println(product);
    }
}

  

(2)使用通配符“? ”。

通配符“?”匹配一個詞,用法見以下代碼:

QueryBuilders.wildcardQuery("字段名", "查?值");

  

具體實現(xiàn)見以下代碼:

@Test
//通配符查詢
public void wildcardQuery2() {
    //查詢條件
    NativeSearchQueryBuilder nativeSearchQueryBuilderQueryBuilder = new NativeSearchQueryBuilder();
         
 
 nativeSearchQueryBuilderQueryBuilder.withQuery(QueryBuilders.wildcardQuery("name","金?"));    
    //搜索,獲取結(jié)果
    Page<Product> products= productRepository.search(nativeSearchQueryBuilderQueryBuilder.build());
    for (Product product: products) {
        System.out.println(product);
    }
)

  

4.分詞模糊查詢??fuzzy query

????????分詞模糊查詢即匹配截取字符串為字前或后加1個詞的文檔,這里通過增加fuzziness (模糊) 屬性來查詢,fuzziness的含義是檢索的term前后增加或減少n個詞的匹配查詢。

用法見以下代碼:

QueryBuilders.fuzzyQuery("字段名","查詢值").fuzziness(Fuzziness.ONE);

  具體實現(xiàn)見以下代碼:

@Test
public void fuzzyQuery(){
    //查詢條件
    NativeSearchQueryBuilder nativeSearchQueryBuilderQueryBuilder
    = new NativeSearchQueryBuilder(); 
        
    nativeSearchQueryBuilderQueryBuilder.withQuery(QueryBuilders.fuzzyQuery("name","士")
            .fuzziness(Fuzziness.ONE));
    //搜索,獲取結(jié)果
    Page<Product> products= productRepository.search (nativeSearchQueryBuilderQueryBuilder.build());
    for (Product product: products){
        System.out.println(product);
    }
}

  

5.相似內(nèi)容推薦

????????相似內(nèi)容的推薦是給定一篇文檔信息,然后向用戶推薦與該文檔相似的文檔。通過?Elasticsearch的More like this查詢接口,可以非常方便地實現(xiàn)基于內(nèi)容的推薦,

用法見以下代碼:

?QueryBuilders.moreLikeThisQuery(new String[] {"字段名"}).addLikeText("查詢值");

如果不指定字段名,則默認(rèn)全部,常用在相似內(nèi)容的推薦上。

13.4.4范圍查詢

將文檔與具有一定范圍內(nèi)字詞的字段進(jìn)行匹配,用法如下。

  • 閉區(qū)間查詢:QueryBuilder queryBuilder?=?QueryBuilders.rangeQuery("字段名").from(“值 1").to("值?2");
  • 開區(qū)間查詢:QueryBuilder queryBuilder?=?QueryBuilders.rangeQuery(”字段名”).from("值 2").includeUpper(false).includeLower(false);//默認(rèn)是true,也就是包含
  • 大于:QueryBuilder queryBuilder?=?QueryBuilders.rangeQuery("字段名").gt("查詢值”);
  • 大于或等于:QueryBuilder queryBuilder = QueryBuilders.rangeQuery("字段名").gte(" 查詢值,
  • 小于:QueryBuilderqueryBuilder =?QueryBuilders.rangeQuery(”字段名”).lt(”查詢值”);
  • 小于或等于:QueryBuilder queryBuilder = QueryBuilders.rangeQuery("字段名").lte("?查詢值”);

13.4.5組合查詢

組合查詢是可以設(shè)置多個條件的查詢方式,用來組合多個查詢,有4種方式。

  • must:代表文檔必須完全匹配條件,相當(dāng)于and,會參與計算分值。
  • mustnot:代表必須不滿足匹配條件。
  • filter:代表返回的文檔必須滿足filter條件,但不會參與計算分值。
  • should:代表返回的文檔可能滿足條件,也可能不滿足條件,有多個should時滿足任何一?個就可以,相當(dāng)于or,可以通過minimum_should_match設(shè)置至少滿足幾個。

13.4.6分頁查詢

使用NativeSearchQueryBuilder實現(xiàn)分頁查詢,用法見以下代碼:

@Test
public void termQuery() {
    //分頁
    int page = 0;
    //每頁文檔數(shù)
    int size=5;
    //構(gòu)建查詢條件
    NativeSearchQueryBuilder nativeSearchQueryBuilderQueryBuilder = new NativeSearchQueryBuilder();
    //查詢詞,只能查詢一個漢字,或一個英文單詞     
    nativeSearchQueryBuilderQueryBuilder.withQuery(QueryBuilders.termQuery("name","富"));
    //搜索,獲取結(jié)果 nativeSearchQueryBuilderQueryBuilder.withPageable(PageRequest.of(page, size));
    Page<Product> products =
productRepository.search(nativeSearchQueryBuilderQueryBuilder.buildO);
    //總條數(shù)
    for (Product product: products) {
        System.out.println(product);
    }
}

  

如果要逬行排序,只要在分頁查詢上構(gòu)建withSort參數(shù)即可,用法見以下代碼:

@Test
//分頁查詢+排序
public void searchByPageAndSort() {
    //分頁:
    int page = 0;
    //每頁文檔數(shù)
    int size = 5;
    //構(gòu)建查詢條件
    NativeSearchQueryBuilder nativeSearchQueryBuilderQueryBuilder = new NativeSearchQueryBuilder();
    //查詢詞,只能查詢一個漢字,或一個英文單詞     
    nativeSearchQueryBuilderQueryBuilder.withQuery(QueryBuilders.termQuery("name","富"));
    //搜索,獲取結(jié)果         
 nativeSearchQueryBuilderQueryBuilder.withSort(SortBuilders.fieldSort("id").order(SortOrder.DESC)); 
    nativeSearchQueryBuilderQueryBuilder.withPageable(PageRequest.of(page, size));
    Page<Product> products = productRepository.search(nativeSearchQueryBuilderQueryBuilder.build());
    //總條數(shù)
    for (Product product: products) {
        System.out.println(product);
    }
}

 

13.4.7 聚合查詢

????????聚合(aggregation )是Elasticsearch的一個強大功能,可以極其方便地實現(xiàn)對數(shù)據(jù)的統(tǒng)計、?分析工作。搜索是查找某些具體的文檔,聚合就是對這些搜索到的文檔進(jìn)行統(tǒng)計,可以聚合出更加細(xì)致的數(shù)據(jù)。它有兩個重要概念。

 

  • Bucket (桶/集合):滿足特定條件的文檔的集合,即分組。
  • Metric (指標(biāo)/度量):對桶內(nèi)的文檔進(jìn)行統(tǒng)計計算(最小值、最大值),簡單理解就是進(jìn)行 、A-A-運算。

聚合由AggregationBuilders類來構(gòu)建,它提供的靜態(tài)方法見表13-3。

功 能

語 法

統(tǒng)計數(shù)量

ValueCountBuilder vcb= AggregationBuilders.count("count id").field("id");

去重統(tǒng)計數(shù)量

CardinalityBuilder cb= AggregationBuilders.cardinality("distinct count id").field("id");

聚合過濾

FilterAggregationBuilder fab二 AggregationBuilders.filter("id_filter").filter(QueryBuilders.query

StringQuery("id:1"));

按字段分組

TermsBuilder tb= AggregationBuilders.terms("group name").field("name");

求和

SumBuilder sumBuilder= AggregationBuilders.sum("suin price").field("price");

求平均值

AvgBuilder ab= AggregationBuilders.avg("avg price").field("price");

求最大值

MaxBuilder mb= AggregationBuilders.max("max price").field("price");

求最小值

MinBuilder min 二 AggregationBuilders.min("min price").field("price");

按日期間隔分組

DateHistogramBuilder dhb二 AggregationBuilders.dateHistogram("dhb dt").field("date");

獲取聚合結(jié)果

TopHitsBuilder thb二 AggregationBuilders.topHits("top hit result");

嵌套的聚合

NestedBuilder nb= AggregationBuilders.nested("negsted quests").path("quests");

反轉(zhuǎn)嵌套

AggregationBuilders.reverseNested("res negsted").path("kps ");

具體用法見以下代碼:

//測試桶
public String searchBybucket() {
    NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();         
    queryBuilder.withSourceFilter(new FetchSourceFilterfnew String[]{""}, null));
    //指定索引的類型,只先從各分片中查詢匹配的文檔,再重新排序和排名,取前size個文檔
    queryBuilder.withSearchType(SearchType.QUERY_THEN_FETCH);
    //指定要查詢的索引庫的名稱和類型,其實就是文檔?Document中設(shè)置的indedName和type     
    queryBuilder.withlndices("goods").withTypes("goods");
    //添加一個新的聚合,聚合類型為terms,聚合名稱為brands,聚合字段為brand     
    queryBuilder.addAggregation(AggregationBuilders.terms("brands").field("brand"));
    //查詢,需要把結(jié)果強轉(zhuǎn)為AggregatedPage類型,AggregatedPage:聚合查詢的結(jié)果類。它是Page<T> 的子接口
    AggregatedPage<Goods> aggPage = (AggregatedPage<Goods>) 
    goodsRepository.search(queryBuilder.build());
    //從結(jié)果中取出名為brands的聚合解析
    //強轉(zhuǎn)為St「ingTerm類型
    StringTerms agg = (StringTerms) aggPage.getAggregation("brands");
    //獲取桶
    List<StringTerms.Bucket> buckets = agg.getBuckets();
    //遍歷
    for (StringTerms.Bucket bucket: buckets) {
        //獲取桶中的key
        System.out.println(bucket.getKeyAsString());
        //獲取桶中的文檔數(shù)量
        System.out.println(bucket.getDocCount());
    }
    return buckets;
}

  還可以嵌套聚合,在聚合AggregationBuilders中使用subAggregation,用法見以下代碼:

queryBuilder.addAggregation(
        AggregationBuilders.terms("brands").field("brand")
        .subAggregation(AggregationBuilders.avg("price_avg").field("price")) //在品牌聚合桶內(nèi)進(jìn)行嵌套聚合);

  這里一定要注意Spring Boot和Elasticsearch的版本是否對應(yīng)。

13.5?實例57:實現(xiàn)產(chǎn)品搜索引擎

????????本實例通過實現(xiàn)一個產(chǎn)品信息的搜索引擎來幫助讀者理解本章所講的知識點及具體使用。創(chuàng)建?實體和接口的方法在前面小節(jié)中已經(jīng)講解過,本節(jié)只講解創(chuàng)建控制器實現(xiàn)搜索API和搜索的視圖展?示方法。

本實例的源代碼可以在,713/ElasticsearchProductSearch”目錄下找到。

(1 )創(chuàng)建搜索控制器,用于構(gòu)建搜索框架,見以下代碼:

〃省略
?Controller
public class Searchcontroller {
    @Autowired
    private ProductRepository productRepository;

    @GetMapping("search")
    public ModelAndView searchByPageAndSort(lnteger start,String key) (
        //分頁:
        if (start == null) {
            start = 0;
        }
        int size=2;〃每頁文檔數(shù)
        //構(gòu)建查詢條件
        NativeSearchQueryBuilder nativeSearchQueryBuilderQueryBuilder = new NativeSearchQueryBuilder();         
        //nativeSearchQueryBuilderQueryBuilder.withQuery(QueryBuilders.matchQuery("name", key));
    
 nativeSearchQueryBuilderQueryBuilder.withQuery(QueryBuilders.multiMatchQuery(key,"name",
"body"));
        /搜索,獲取結(jié)果
        nativeSearchQueryBuilderQueryBuilder.withSort(SortBuilders.fieldSort("id")
                .order(SortOrder.DESC));
        nativeSearchQueryBuilderQueryBuilder.withPageable(PageRequest.of(start, size));
        Page<Product> products = productRepository.search(nativeSearchQueryBuilderQueryBuilder.build()); 
        //總條數(shù) 
        for (Product product: products) {
            System.out.println(product);
        }
        ModelAndView mav = new ModelAndView("search");
        mav.addObject("page", products);
        mav.addObject("keys", key);
        return mav;
    }
}

  

(2)創(chuàng)建顯示視圖。

創(chuàng)建用于展示數(shù)據(jù)的前端頁面,具體見以下代碼:

<!—省略...一〉
<body>
<div class ="contain?!敢?fluid"〉
<div><span >搜索詞:</span><span th:text="$(keys)">mav</span></div>
<div class="row-fluid">
<div class="span12">
<div th:each="item : $(page.content}">
<span th:text=,,$(item.id}">id</span>
<span th:text="$(item.name}">name</span> <span th:text="$(item.body}">body</span></div>
</div>
<div>
<a th:href=,,@{/search(key=${keys},start=O,)}n>[MZS]</a>
<a th:if="$(not page.isFirst())" th:href="@(/search(key=${keys},start=${page.number-1 })}">[± 頁]<7a>
<a th:if="$(not page.isLast())" th:href="@(/search(key=${keys),start=${page.number+1})}">[T 頁]</a>
<a th:href="@(/search(key=${keys},start=$(page.totalPages-1})}">[^^]</h>
</div>
</div>
</div>
</body>
</html>

  

13.6 Solr—搜索應(yīng)用服務(wù)器

13.6.1?了解?Solr

Solr是一個獨立的企業(yè)級搜索應(yīng)用服務(wù)器,對外提供API接口。用戶可以通過HTTP請求向?搜索引擎服務(wù)器提交一定格式的XML文件,生成索引;也可以通過HTTP GET操作提出查找請求, 并得到XML格式的返回結(jié)果。Solr現(xiàn)在支持多種返回結(jié)果。

13.6.2安裝配置Solr

1、Solr安裝

(1 )訪問鏡像網(wǎng)站,下載Solr壓縮包。

(2)在下載完成后解壓文件,在"cmd”控制臺進(jìn)入"solr/bin”目錄下,輸入“solr start” 命令啟動Sol「o

如果出現(xiàn)以下提示,則表示成功啟動。

INFO - 2019-05-09 10:30:09.043; org.apache.solr.util.configuration.SSLCredentialProviderFactory; Processing SSL Credential Provider chain: env;sysprop
Waiting up to 30 to see Solr running on port 8983
Started Solr server on port 8983. Happy searching!

  

(3)訪問?uhttp://localhost:8983/solr/#/n,就可以看到已經(jīng)啟動了。

常用命令如下。

  • 停止:Msolr stop -p 8983 ”?或?“sole stop - oil”。
  • 查看運行狀態(tài):sol「status。

2、Solr配置

(1 )進(jìn)入Solr的安裝目錄下的server/solr/,創(chuàng)建一個名字為new_core的文件夾。

(2)將?conf?目錄(在安裝目錄/servei7soli7configsets/sample_techproducts_configs?下) 復(fù)制到new_core目錄下。

(3 )訪問?“http://localhost:8983/sol「/#/”。

單擊導(dǎo)航欄的“Core Admin”,在彈出窗口中單擊“Add Core”命令,彈出如圖13-8所示?的對話框,輸入名字和目錄名,再單擊“AddCore”按鈕,完成創(chuàng)建。

《Spring Boot 實戰(zhàn)派》--13.集成NoSQL數(shù)據(jù)庫,實現(xiàn)Elasticsearch和Solr搜索引擎

13.6.3?整合?Spring Boot?和?Solr

(1)?添加依賴,見以下代碼:

<dependency>
    <groupld>org.springframework.boot</groupld>
    <artifactld>spring-boot-starter-data-solr</artifactld>
</dependency>

  

(2)?寫入Solr配置。

在application.properties文件中進(jìn)行Sol「配置,寫入下面配置信息即可。

spring.data.solr.host=http://localhost:8983/solr/new_core

  

13.7?實例58:在Sping Boot中集成Solr,實現(xiàn)數(shù)據(jù)的增加、刪除、?修改和查詢

本實例在Sol「中實現(xiàn)數(shù)據(jù)的增加、刪除、修改和查詢。

本實例的源代碼可以在“/13/Solr”目錄下找到。

13.7.1?創(chuàng)建?User 類

User類必須繼承可序列化接口,見以下代碼:

@Data
public class User implements Serializable {
    @Field("id")
    //使用這個注釋,里面的名字是根據(jù)Solr數(shù)據(jù)庫中的配置來決定的 
    private String id;

    @Field("name") 
    private String name;
}

  

13.7.2測試增加、刪除、修改和查詢功能

(1)?測試增加功能。

構(gòu)造一篇文檔,實例化一個對象,向Solr中添加數(shù)據(jù),見以下代碼:

@Test
public void addUser() throws lOException, SolrServerException { 
    User user = new User(); 
    user.setld("8888888"); 
    user.setName("龍知然"); 
    solrClient.addBean(user);
    solrClient.commit();
}

  

(2)?測試增加功能,根據(jù)id查詢剛剛添加的內(nèi)容,見以下代碼:

@Test
public void getByldFromSolr() throws lOException, SolrServerException { 
    //根據(jù)id查詢內(nèi)容
    String id = "8888888";
    SolrDocument solrDocument = solrClient.getByld(id);
    //獲取 filedName
    Collection<String> fieldNames = solrDocument.getFieldNames();
    //獲取file名和內(nèi)容
    Map<String, Object> fieldValueMap = solrDocument.getFieldValueMap();
    List<SolrDocument> childDocuments = solrDocument.getChildDocuments();
    String results = solrDocument.toString();
    System.out.println(results);
}

  

運行測試,控制臺輸出如下結(jié)果:

SolrDocument{id=8888888, name=龍知然,version = 1633023077954617344}

 

(3)?測試修改功能,根據(jù)id修改內(nèi)容,見以下代碼 

@RequestMapping("/updateUser")
public void updateUser() throws lOException, SolrServerException {
    User user = new User();
    user.setld("8888888");
    user.setName("知然");
    solrClient.addBean(user);
    soIrClient.commit();
}

  

修改之后的值如下:

Solr Document{id=8888888, name=知然,_version_=1633023690698391552}

  

可以看到,內(nèi)容已經(jīng)變化,所謂Sol「的更新操作,就是對相同id的文檔重新添加一次。修改之?后,Version變得不一樣了。

(4)?測試刪除功能,根據(jù)id刪除內(nèi)容,見以下代碼:

@Test
public void delByld() throws lOException, SolrServerException {
    //根據(jù)id刪除信息
    UpdateResponse updateResponse = solrClient.deleteByld("8888888");
    //執(zhí)行的時間
    long elapsedTime = updateResponse.getElapsedTime();
    int qTime = updateResponse.getQTime();
    //請求地址
    String requestUrl = updateResponse.getRequestUrl();
    //請求的結(jié)果{responseHeader=(status=0,QTime=2)}
    NamedList<Object> response = updateResponse.getResponse();
    //請求結(jié)果的頭(status=0,QTime=2)
    NamedList responseHeader = updateResponse.getResponseHeader();
    //請求的狀態(tài)0
    solrClient.commit();
    int status = updateResponse.getStatus();
    //成功,則返回0,如果沒有文檔被刪除,也會返回0,代表根本沒有
}

  

刪除全部可以用以下代碼:

solrClient.deleteByQuery("*:*");

  

(5)?實現(xiàn)文檔高亮顯示,見以下代碼:

@Test
public void queryAII() throws lOException, SolrServerException {
    SoIrQuery soIrQuery = new SoIrQuery();
    〃設(shè)置默認(rèn)搜索域
    solrQuery.setQuery("*:*");
    soIrQuery.set("q", "知然"); 
    solrQuery.add("q", "name:然");
    〃設(shè)置返回結(jié)果的排序規(guī)則
    soIrQuery.setSort("id", SolrQuery.ORDER.asc);
    〃設(shè)置查詢的條數(shù)
    solrQuery.setRows(50);
    〃設(shè)置查詢的開始
    solrQuery.setStart(0);
    //設(shè)置分頁參數(shù)
    solrQuery.setStart(0); 
    solrQuery.setRows(20);
    〃設(shè)置高亮
    solrQuery.setHighlight(true);
    〃設(shè)置高亮的字段
    solrQuery.addHighlightField("name");
    〃設(shè)置高亮的樣式
    solrQuery-setHighlightSimplePre("<font color='red'>");           
    solrQuery.setHighlightSimplePost("</font>");
    System.out.println(solrQuery);
    QueryResponse response = solrClient.query(solrQuery);
    //返回高亮顯示結(jié)果
    Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();         
    //response.getResults();查詢返回的結(jié)果
    SoIrDocumentList documentList = response.getResults();
    long numFound = documentList.getNumFound();
    System.out.println("共查詢到的文檔數(shù)量:"+ numFound);
    for (SoIrDocument soIrDocument: documentList) { 
        System.out.println(solrDocument);
        System.out.println(solrDocument.get("name"));
    }
    System.out.println(highlighting);
}

  

運行上面代碼,在控制臺中輸出如下結(jié)果:

q=知然&q=name:然&sort=id+asc&rows=20&start=0&hl=true&hl.fl=name&hl.simple.pre=<font+color='red,>
&hl.simple.post=</font>
總共查詢到的文檔數(shù)量:3
SolrDocument(id=ld3cbb8a541 b45759b 1 a59a86ddd0f9b, name=龍知然 4,
_version_=l 633022994022400000)
蘢知然4
SolrDocument {id=3 ddb0995b0c04fc0be3 c34612c33992c, name=龍知然 4, _version_=1633022357082734594}
蘢知然4
SolrDocument{id=bb37d6fI96ad43bc8654f29f2e9f389f, name=龍知然 4, sex=男,address=武漢 4, _version_=1626411498284777473)
蘢知然j
(1 d3cbb8a541 b45759b 1 a59a86ddd0f9b= {name=[^.<fbnt coloi^'red'>^p</fbntxfbnt colorTedA 然 </fbnt>4]), 3ddb0995b0c04fc0be3c34612c33992c= {name=[^.<fbnt coloi=Yed^^p^fbntXfbnt coloi='red^^^/fbnW]), bb37d6f!96ad43bc8654f29f2e9f389仁{name=[龍 vfbnt coloi^'red^^p^fontxfbnt color='red' >然 </fbnt>4]}}

  

從〈font color='red‘>然</font>中可以看出,查詢結(jié)果已經(jīng)高亮化了,對查詢關(guān)鍵詞輸岀紅色?字體。

13.8?對比?Elasticsearch?和?Solr

1. Elasticsearch和Solr的市場關(guān)注度

《Spring Boot 實戰(zhàn)派》--13.集成NoSQL數(shù)據(jù)庫,實現(xiàn)Elasticsearch和Solr搜索引擎

2. Elasticsearch?和?Solr?的優(yōu)缺點

(1 ) Solr的優(yōu)點。

Solr有一個更大' 更成熟的用戶' 開發(fā)和貢獻(xiàn)者社區(qū)。

  • 支持添加多種格式的索引,如:HTML. PDF、微軟Office系列軟件格式,以及JSON、?XML、CSV等純文本格式。
  • 比較成熟、穩(wěn)定。
  • 搜索速度更快(不建索引時)。
  • Soli?利用Zookeeper進(jìn)行分布式管理,而Elasticsearch自身帶有分布式協(xié)調(diào)管理功能。?如果項目本身使用了?Zookeeper,那Solr可能是最好選擇。有時缺點在特點場景下可能會?變成優(yōu)點。
  • 如果項目后期升級,要朝著Hadoop這塊發(fā)展,當(dāng)數(shù)據(jù)量較大時,用Hadoop處理數(shù)據(jù),?Solr可以很方便地與Hadoop結(jié)合。

(2)?Elasticsearch 的優(yōu)點。

  • Elasticsearch本身是分布式、分發(fā)實時的,不需要其他組件。
  • Elasticsearch完全支持Apache Lucene的接近實時的搜索。
  • 它處理多用戶不需要特殊配置,而Solr則需要更多的高級設(shè)置。
  • Elasticsearch采用Gateway的概念,備份更加簡單。各節(jié)點組成對等的網(wǎng)絡(luò)結(jié)構(gòu),某節(jié)?點出現(xiàn)故障會自動分配其他節(jié)點代替其進(jìn)行工作。

(3)?Solr的缺點。?

  • 建立索引時,搜索效率下降,實時索引搜索效率不高。
  • 實時搜索應(yīng)用效率明顯低于Elasticsearch。

(4 ) Elasticsearch 的缺點。

  • 沒有Solr的生態(tài)系統(tǒng)發(fā)達(dá)。
  • 僅支持JSON文件格式。
  • 本身更注重核心功能,高級功能多由第三方插件提供。

總結(jié):Solr是傳統(tǒng)搜索應(yīng)用的有力解決方案,但Elasticsearch更適用于新興的實時搜索應(yīng)用。文章來源地址http://www.zghlxwxcb.cn/news/detail-407408.html

到了這里,關(guān)于《Spring Boot 實戰(zhàn)派》--13.集成NoSQL數(shù)據(jù)庫,實現(xiàn)Elasticsearch和Solr搜索引擎的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • SpringBoot + Vue前后端分離項目實戰(zhàn) || 二:Spring Boot后端與數(shù)據(jù)庫連接

    SpringBoot + Vue前后端分離項目實戰(zhàn) || 二:Spring Boot后端與數(shù)據(jù)庫連接

    系列文章: SpringBoot + Vue前后端分離項目實戰(zhàn) || 一:Vue前端設(shè)計 SpringBoot + Vue前后端分離項目實戰(zhàn) || 二:Spring Boot后端與數(shù)據(jù)庫連接 SpringBoot + Vue前后端分離項目實戰(zhàn) || 三:Spring Boot后端與Vue前端連接 SpringBoot + Vue前后端分離項目實戰(zhàn) || 四:用戶管理功能實現(xiàn) SpringBoot + Vue前后

    2024年02月11日
    瀏覽(53)
  • 【100天精通python】Day44:python網(wǎng)絡(luò)爬蟲開發(fā)_爬蟲基礎(chǔ)(爬蟲數(shù)據(jù)存儲:基本文件存儲,MySQL,NoSQL:MongDB,Redis 數(shù)據(jù)庫存儲+實戰(zhàn)代碼)

    目錄 1 數(shù)據(jù)存儲 1.1 爬蟲存儲:基本文件存儲 1.2 爬蟲存儲:使用MySQL 數(shù)據(jù)庫 1.3 爬蟲 NoSQL 數(shù)據(jù)庫使用 1.3.1 MongoDB 簡介

    2024年02月11日
    瀏覽(24)
  • 【Spring Boot】Spring Boot 配置 Hikari 數(shù)據(jù)庫連接池

    數(shù)據(jù)庫連接池是一個提高程序與數(shù)據(jù)庫的連接的優(yōu)化,連接池它主要作用是提高性能、節(jié)省資源、控制連接數(shù)、連接管理等操作; 程序中的線程池與之同理,都是為了優(yōu)化、提高性能。

    2024年02月11日
    瀏覽(29)
  • Spring Boot:數(shù)據(jù)庫的整合

    Spring Boot:數(shù)據(jù)庫的整合

    在 Spring Boot :Web開發(fā)之視圖模板技術(shù)的整合 文章中,介紹了 Spring Boot 整合視圖模板技術(shù)。然而,僅僅整合視圖模板技術(shù)可能還不能滿足所有業(yè)務(wù)需求,因此還需要進(jìn)一步擴展 Spring MVC 的默認(rèn)配置。 簡單補充說明 : 擴展 Spring Boot 中的 Spring MVC 默認(rèn)配置通常涉及實現(xiàn) WebMvcC

    2024年04月13日
    瀏覽(32)
  • Spring Boot對接Oracle數(shù)據(jù)庫

    Spring Boot對接Oracle數(shù)據(jù)庫

    最近學(xué)習(xí)了Oracle數(shù)據(jù)庫,那么如何使用Spring Boot和MyBatis Plus對接Oracle數(shù)據(jù)庫呢? 這就有了這篇隨記,具體流程如下 創(chuàng)建一個空的Maven工程,導(dǎo)入如下依賴: tips:這里碰到一個坑,我本機適用的Oracle數(shù)據(jù)庫版本是11g XE,所以要使用的驅(qū)動為ojdbc5/ojdbc6,不然連接老會失敗。 在配

    2024年02月09日
    瀏覽(22)
  • 【Spring Boot】通過AOP攔截Spring Boot日志并將其存入數(shù)據(jù)庫

    【Spring Boot】通過AOP攔截Spring Boot日志并將其存入數(shù)據(jù)庫

    在軟件開發(fā)中,常常需要記錄系統(tǒng)運行時的日志。日志記錄有助于排查系統(tǒng)問題、優(yōu)化系統(tǒng)性能、監(jiān)控操作行為等。本文將介紹如何使用Spring Boot和AOP技術(shù)實現(xiàn)攔截系統(tǒng)日志并保存到數(shù)據(jù)庫中的功能。 本文將通過以下步驟實現(xiàn)攔截系統(tǒng)日志并保存到數(shù)據(jù)庫中的功能: 配置數(shù)據(jù)

    2024年02月10日
    瀏覽(21)
  • Spring Boot MySQL數(shù)據(jù)庫的使用

    Spring Boot MySQL數(shù)據(jù)庫的使用

    目錄 簡介Spring Boot Spring Boot的優(yōu)點 Spring Boot連接數(shù)據(jù)庫 1.添加依賴 1.2開啟連接數(shù)據(jù)庫 1.2.1 如果沒有開啟數(shù)據(jù)庫運行程序的時候會出現(xiàn)這樣的報錯這就是沒有連接數(shù)據(jù)庫,所以我們開啟數(shù)據(jù)庫即可使用。 1.2.2 我的名字是MySQL110所以一會用命令字符開啟數(shù)據(jù)庫的時候用的就是這

    2024年04月10日
    瀏覽(22)
  • Spring Boot如何訪問不同的數(shù)據(jù)庫

    ????????在Spring Boot應(yīng)用中連接多個數(shù)據(jù)庫或數(shù)據(jù)源可以使用多種方式,下面介紹兩種常用的方法: 1、使用Spring Boot官方支持的多數(shù)據(jù)源配置 ? ? ? ? spring boot提供了官方支持的多數(shù)據(jù)源配置,可以簡單地配置和管理多個數(shù)據(jù)源。 ????????需要在application.properties文件中

    2024年02月13日
    瀏覽(31)
  • Spring Boot項目實現(xiàn)無數(shù)據(jù)庫啟動

    Spring Boot項目實現(xiàn)無數(shù)據(jù)庫啟動

    今天需要創(chuàng)建一個不連接數(shù)據(jù)庫的Spring Boot工程, 結(jié)果一切配置好后項目卻啟動失敗, 提示如下: 查詢了一下資料, 發(fā)現(xiàn)原來Spring Boot啟動時是默認(rèn)是要連接數(shù)據(jù)庫的, 這樣一來只需要把數(shù)據(jù)庫的一些配置排除掉就可以了: 重新啟動, 項目成功運行了。另外, pom.xml文件中也不要引入

    2024年02月15日
    瀏覽(23)
  • 【Spring Boot】數(shù)據(jù)庫持久層框架MyBatis — Spring Boot構(gòu)建MyBatis應(yīng)用程序

    Spring Boot是用于快速構(gòu)建Spring應(yīng)用程序的框架。MyBatis是一種Java持久化框架,可以幫助開發(fā)人員輕松地管理數(shù)據(jù)庫。將Spring Boot與MyBatis結(jié)合使用可以使開發(fā)人員更容易地創(chuàng)建和管理數(shù)據(jù)庫應(yīng)用程序。 以下是使用Spring Boot構(gòu)建MyBatis應(yīng)用程序的步驟: 添加MyBatis依賴項:在項目的

    2024年02月10日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包