您當前的位置:首頁 > 舞蹈

mall整合Elasticsearch實現商品搜尋

作者:由 macrozheng 發表于 舞蹈時間:2020-01-08

本文主要講解mall整合Elasticsearch的過程,以實現商品資訊在Elasticsearch中的匯入、查詢、修改、刪除為例。

SpringBoot實戰電商專案mall(25k+star)地址:

https://

github。com/macrozheng/m

all

專案使用框架介紹

Elasticsearch

Elasticsearch 是一個分散式、可擴充套件、實時的搜尋與資料分析引擎。 它能從專案一開始就賦予你的資料以搜尋、分析和探索的能力,可用於實現全文搜尋和實時資料統計。

Elasticsearch的安裝和使用

下載Elasticsearch6。2。2的zip包,並解壓到指定目錄,下載地址:

https://www。

elastic。co/cn/downloads

/past-releases/elasticsearch-6-2-2

mall整合Elasticsearch實現商品搜尋

安裝中文分詞外掛,在elasticsearch-6。2。2\bin目錄下執行以下命令:elasticsearch-plugin install

https://

github。com/medcl/elasti

csearch-analysis-ik/releases/download/v6。2。2/elasticsearch-analysis-ik-6。2。2。zip

mall整合Elasticsearch實現商品搜尋

執行bin目錄下的elasticsearch。bat啟動Elasticsearch

mall整合Elasticsearch實現商品搜尋

下載Kibana,作為訪問Elasticsearch的客戶端,請下載6。2。2版本的zip包,並解壓到指定目錄,下載地址:

https://

artifacts。elastic。co/do

wnloads/kibana/kibana-6。2。2-windows-x86_64。zip

mall整合Elasticsearch實現商品搜尋

執行bin目錄下的kibana。bat,啟動Kibana的使用者介面

mall整合Elasticsearch實現商品搜尋

訪問http://localhost:5601 即可開啟Kibana的使用者介面

mall整合Elasticsearch實現商品搜尋

Spring Data Elasticsearch

Spring Data Elasticsearch是Spring提供的一種以Spring Data風格來操作資料儲存的方式,它可以避免編寫大量的樣板程式碼。

常用註解

@Document

//標示對映到Elasticsearch文件上的領域物件

public

@interface

Document

{

//索引庫名次,mysql中資料庫的概念

String

indexName

();

//文件型別,mysql中表的概念

String

type

()

default

“”

//預設分片數

short

shards

()

default

5

//預設副本數量

short

replicas

()

default

1

}

@Id

//表示是文件的id,文件可以認為是mysql中表行的概念

public

@interface

Id

{

}

@Field

public

@interface

Field

{

//文件中欄位的型別

FieldType

type

()

default

FieldType

Auto

//是否建立倒排索引

boolean

index

()

default

true

//是否進行儲存

boolean

store

()

default

false

//分詞器名次

String

analyzer

()

default

“”

}

//為文件自動指定元資料型別

public

enum

FieldType

{

Text

//會進行分詞並建了索引的字元型別

Integer

Long

Date

Float

Double

Boolean

Object

Auto

//自動判斷欄位型別

Nested

//巢狀物件型別

Ip

Attachment

Keyword

//不會進行分詞建立索引的型別

}

Sping Data方式的資料操作

繼承ElasticsearchRepository介面可以獲得常用的資料操作方法

mall整合Elasticsearch實現商品搜尋

可以使用衍生查詢

在介面中直接指定查詢方法名稱便可查詢,無需進行實現,如商品表中有商品名稱、標題和關鍵字,直接定義以下查詢,就可以對這三個欄位進行全文搜尋。

/**

* 搜尋查詢

*

* @param name 商品名稱

* @param subTitle 商品標題

* @param keywords 商品關鍵字

* @param page 分頁資訊

* @return

*/

Page

<

EsProduct

>

findByNameOrSubTitleOrKeywords

String

name

String

subTitle

String

keywords

Pageable

page

);

在idea中直接會提示對應欄位

mall整合Elasticsearch實現商品搜尋

使用@Query註解可以用Elasticsearch的DSL語句進行查詢

@Query

“{”

bool

“ : {”

must

“ : {”

field

“ : {”

name

“ : ”

0

“}}}}”

Page

<

EsProduct

>

findByName

String

name

Pageable

pageable

);

專案使用表說明

pms_product

:商品資訊表

pms_product_attribute

:商品屬性引數表

pms_product_attribute_value

:儲存產品引數值的表

整合Elasticsearch實現商品搜尋

在pom。xml中新增相關依賴

<!——Elasticsearch相關依賴——>

org。springframework。boot

spring-boot-starter-data-elasticsearch

修改SpringBoot配置檔案

修改application。yml檔案,在spring節點下新增Elasticsearch相關配置。

data:

elasticsearch:

repositories:

enabled: true

cluster-nodes: 127。0。0。1:9300 # es的連線地址及埠號

cluster-name: elasticsearch # es叢集的名稱

新增商品文件物件EsProduct

不需要中文分詞的欄位設定成@Field(type = FieldType。Keyword)型別,需要中文分詞的設定成@Field(analyzer = “ik_max_word”,type = FieldType。Text)型別。

package

com。macro。mall。tiny。nosql。elasticsearch。document

import

org。springframework。data。annotation。Id

import

org。springframework。data。elasticsearch。annotations。Document

import

org。springframework。data。elasticsearch。annotations。Field

import

org。springframework。data。elasticsearch。annotations。FieldType

import

java。io。Serializable

import

java。math。BigDecimal

import

java。util。List

/**

* 搜尋中的商品資訊

* Created by macro on 2018/6/19。

*/

@Document

indexName

=

“pms”

type

=

“product”

shards

=

1

replicas

=

0

public

class

EsProduct

implements

Serializable

{

private

static

final

long

serialVersionUID

=

-

1L

@Id

private

Long

id

@Field

type

=

FieldType

Keyword

private

String

productSn

private

Long

brandId

@Field

type

=

FieldType

Keyword

private

String

brandName

private

Long

productCategoryId

@Field

type

=

FieldType

Keyword

private

String

productCategoryName

private

String

pic

@Field

analyzer

=

“ik_max_word”

type

=

FieldType

Text

private

String

name

@Field

analyzer

=

“ik_max_word”

type

=

FieldType

Text

private

String

subTitle

@Field

analyzer

=

“ik_max_word”

type

=

FieldType

Text

private

String

keywords

private

BigDecimal

price

private

Integer

sale

private

Integer

newStatus

private

Integer

recommandStatus

private

Integer

stock

private

Integer

promotionType

private

Integer

sort

@Field

type

=

FieldType

Nested

private

List

<

EsProductAttributeValue

>

attrValueList

//省略了所有getter和setter方法

}

新增EsProductRepository介面用於操作Elasticsearch

繼承ElasticsearchRepository介面,這樣就擁有了一些基本的Elasticsearch資料操作方法,同時定義了一個衍生查詢方法。

package

com。macro。mall。tiny。nosql。elasticsearch。repository

import

com。macro。mall。tiny。nosql。elasticsearch。document。EsProduct

import

org。springframework。data。domain。Page

import

org。springframework。data。domain。Pageable

import

org。springframework。data。elasticsearch。repository。ElasticsearchRepository

/**

* 商品ES操作類

* Created by macro on 2018/6/19。

*/

public

interface

EsProductRepository

extends

ElasticsearchRepository

<

EsProduct

Long

>

{

/**

* 搜尋查詢

*

* @param name 商品名稱

* @param subTitle 商品標題

* @param keywords 商品關鍵字

* @param page 分頁資訊

* @return

*/

Page

<

EsProduct

>

findByNameOrSubTitleOrKeywords

String

name

String

subTitle

String

keywords

Pageable

page

);

}

新增EsProductService介面

package

com。macro。mall。tiny。service

import

com。macro。mall。tiny。nosql。elasticsearch。document。EsProduct

import

org。springframework。data。domain。Page

import

java。util。List

/**

* 商品搜尋管理Service

* Created by macro on 2018/6/19。

*/

public

interface

EsProductService

{

/**

* 從資料庫中匯入所有商品到ES

*/

int

importAll

();

/**

* 根據id刪除商品

*/

void

delete

Long

id

);

/**

* 根據id建立商品

*/

EsProduct

create

Long

id

);

/**

* 批次刪除商品

*/

void

delete

List

<

Long

>

ids

);

/**

* 根據關鍵字搜尋名稱或者副標題

*/

Page

<

EsProduct

>

search

String

keyword

Integer

pageNum

Integer

pageSize

);

}

新增EsProductService介面的實現類EsProductServiceImpl

package

com。macro。mall。tiny。service。impl

import

com。macro。mall。tiny。dao。EsProductDao

import

com。macro。mall。tiny。nosql。elasticsearch。document。EsProduct

import

com。macro。mall。tiny。nosql。elasticsearch。repository。EsProductRepository

import

com。macro。mall。tiny。service。EsProductService

import

org。slf4j。Logger

import

org。slf4j。LoggerFactory

import

org。springframework。beans。factory。annotation。Autowired

import

org。springframework。data。domain。Page

import

org。springframework。data。domain。PageRequest

import

org。springframework。data。domain。Pageable

import

org。springframework。stereotype。Service

import

org。springframework。util。CollectionUtils

import

java。util。ArrayList

import

java。util。Iterator

import

java。util。List

/**

* 商品搜尋管理Service實現類

* Created by macro on 2018/6/19。

*/

@Service

public

class

EsProductServiceImpl

implements

EsProductService

{

private

static

final

Logger

LOGGER

=

LoggerFactory

getLogger

EsProductServiceImpl

class

);

@Autowired

private

EsProductDao

productDao

@Autowired

private

EsProductRepository

productRepository

@Override

public

int

importAll

()

{

List

<

EsProduct

>

esProductList

=

productDao

getAllEsProductList

null

);

Iterable

<

EsProduct

>

esProductIterable

=

productRepository

saveAll

esProductList

);

Iterator

<

EsProduct

>

iterator

=

esProductIterable

iterator

();

int

result

=

0

while

iterator

hasNext

())

{

result

++;

iterator

next

();

}

return

result

}

@Override

public

void

delete

Long

id

{

productRepository

deleteById

id

);

}

@Override

public

EsProduct

create

Long

id

{

EsProduct

result

=

null

List

<

EsProduct

>

esProductList

=

productDao

getAllEsProductList

id

);

if

esProductList

size

()

>

0

{

EsProduct

esProduct

=

esProductList

get

0

);

result

=

productRepository

save

esProduct

);

}

return

result

}

@Override

public

void

delete

List

<

Long

>

ids

{

if

(!

CollectionUtils

isEmpty

ids

))

{

List

<

EsProduct

>

esProductList

=

new

ArrayList

<>();

for

Long

id

ids

{

EsProduct

esProduct

=

new

EsProduct

();

esProduct

setId

id

);

esProductList

add

esProduct

);

}

productRepository

deleteAll

esProductList

);

}

}

@Override

public

Page

<

EsProduct

>

search

String

keyword

Integer

pageNum

Integer

pageSize

{

Pageable

pageable

=

PageRequest

of

pageNum

pageSize

);

return

productRepository

findByNameOrSubTitleOrKeywords

keyword

keyword

keyword

pageable

);

}

}

新增EsProductController定義介面

package

com。macro。mall。tiny。controller

import

com。macro。mall。tiny。common。api。CommonPage

import

com。macro。mall。tiny。common。api。CommonResult

import

com。macro。mall。tiny。nosql。elasticsearch。document。EsProduct

import

com。macro。mall。tiny。service。EsProductService

import

io。swagger。annotations。Api

import

io。swagger。annotations。ApiOperation

import

org。springframework。beans。factory。annotation。Autowired

import

org。springframework。data。domain。Page

import

org。springframework。stereotype。Controller

import

org。springframework。web。bind。annotation。*

import

java。util。List

/**

* 搜尋商品管理Controller

* Created by macro on 2018/6/19。

*/

@Controller

@Api

tags

=

“EsProductController”

description

=

“搜尋商品管理”

@RequestMapping

“/esProduct”

public

class

EsProductController

{

@Autowired

private

EsProductService

esProductService

@ApiOperation

value

=

“匯入所有資料庫中商品到ES”

@RequestMapping

value

=

“/importAll”

method

=

RequestMethod

POST

@ResponseBody

public

CommonResult

<

Integer

>

importAllList

()

{

int

count

=

esProductService

importAll

();

return

CommonResult

success

count

);

}

@ApiOperation

value

=

“根據id刪除商品”

@RequestMapping

value

=

“/delete/{id}”

method

=

RequestMethod

GET

@ResponseBody

public

CommonResult

<

Object

>

delete

@PathVariable

Long

id

{

esProductService

delete

id

);

return

CommonResult

success

null

);

}

@ApiOperation

value

=

“根據id批次刪除商品”

@RequestMapping

value

=

“/delete/batch”

method

=

RequestMethod

POST

@ResponseBody

public

CommonResult

<

Object

>

delete

@RequestParam

“ids”

List

<

Long

>

ids

{

esProductService

delete

ids

);

return

CommonResult

success

null

);

}

@ApiOperation

value

=

“根據id建立商品”

@RequestMapping

value

=

“/create/{id}”

method

=

RequestMethod

POST

@ResponseBody

public

CommonResult

<

EsProduct

>

create

@PathVariable

Long

id

{

EsProduct

esProduct

=

esProductService

create

id

);

if

esProduct

!=

null

{

return

CommonResult

success

esProduct

);

}

else

{

return

CommonResult

failed

();

}

}

@ApiOperation

value

=

“簡單搜尋”

@RequestMapping

value

=

“/search/simple”

method

=

RequestMethod

GET

@ResponseBody

public

CommonResult

<

CommonPage

<

EsProduct

>>

search

@RequestParam

required

=

false

String

keyword

@RequestParam

required

=

false

defaultValue

=

“0”

Integer

pageNum

@RequestParam

required

=

false

defaultValue

=

“5”

Integer

pageSize

{

Page

<

EsProduct

>

esProductPage

=

esProductService

search

keyword

pageNum

pageSize

);

return

CommonResult

success

CommonPage

restPage

esProductPage

));

}

}

進行介面測試

將資料庫中資料匯入到Elasticsearch

mall整合Elasticsearch實現商品搜尋

mall整合Elasticsearch實現商品搜尋

進行商品搜尋

mall整合Elasticsearch實現商品搜尋

mall整合Elasticsearch實現商品搜尋

專案原始碼地址

https://

github。com/macrozheng/m

all-learning/tree/master/mall-tiny-06