前言
本文記錄谷粒商城高級(jí)篇的 Elasticsearch 進(jìn)階檢索部分,續(xù)上之前記錄的 Elasticsearch入門(mén)篇。
一、SearchAPI
ES 支持兩種基本方式檢索 :
- 一個(gè)是通過(guò)使用 REST request URI 發(fā)送搜索參數(shù)(uri + 檢索參數(shù))
- 另一個(gè)是通過(guò)使用 REST request body 來(lái)發(fā)送它們(uri + 請(qǐng)求體)
1.1 URL 后接參數(shù)檢索
GET bank/_search 檢索 bank 下所有信息,包括 type 和 docs
GET bank/_search?q=*&sort=account_number:asc 請(qǐng)求參數(shù)方式檢索
響應(yīng)結(jié)果解釋?zhuān)?took - Elasticsearch 執(zhí)行搜索的時(shí)間(毫秒)
time_out - 告訴我們搜索是否超時(shí)
_shards - 告訴我們多少個(gè)分片被搜索了,以及統(tǒng)計(jì)了成功/失敗的搜索分片
hits - 搜索結(jié)果
hits.total - 搜索結(jié)果
hits.hits - 實(shí)際的搜索結(jié)果數(shù)組(默認(rèn)為前 10 的文檔)
sort - 結(jié)果的排序 key(鍵)(沒(méi)有則按 score 排序)
score 和 max_score - 相關(guān)性得分和最高得分(全文檢索用)
1.2 URL 加請(qǐng)求體檢索
請(qǐng)求體中寫(xiě)查詢(xún)條件,語(yǔ)法:
GET bank/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"account_number": "asc"
},
{
"balance": "desc"
}
]
}
示例:查詢(xún)出所有,先按照 accout_number 升序排序,再按照 balance 降序排序
二、Query DSL
2.1 基本語(yǔ)法格式
Elasticsearch 提供了一個(gè)可以執(zhí)行查詢(xún)的 Json 風(fēng)格的 DSL(domain-specific language 領(lǐng)域特定語(yǔ)言)。這個(gè)被稱(chēng)為 Query DSL。該查詢(xún)語(yǔ)言非常全面,并且剛開(kāi)始的時(shí)候感覺(jué)有點(diǎn)復(fù)雜,真正學(xué)好它的方法是從一些基礎(chǔ)的示例開(kāi)始的。
GET bank/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"balance": {
"order": "desc"
}
}
],
"from": 10,
"size": 10,
"_source": ["balance", "firstname"]
}
示例:查詢(xún)所有記錄,按照 balance 降序排序,只返回第 11 條記錄到第 20 條記錄,只顯示 balance 和 firstname 字段。
query 定義如何查詢(xún),
match_all 查詢(xún)類(lèi)型【代表查詢(xún)所有的所有】,es 中可以在 query 中組合非常多的查
詢(xún)類(lèi)型完成復(fù)雜查詢(xún)
除了 query 參數(shù)之外,我們也可以傳遞其它的參數(shù)以改變查詢(xún)結(jié)果。如 sort,size
from + size 限定,完成分頁(yè)功能
sort 排序,多字段排序,會(huì)在前序字段相等時(shí)后續(xù)字段內(nèi)部排序,否則以前序?yàn)闇?zhǔn)
_source 返回部分字段
2.2 匹配查詢(xún) match
1.基本類(lèi)型 ( 非字符串 ) ,精確匹配
GET bank/_search
{
"query": {
"match": {
"account_number": "30"
}
}
}
2.字符串,全文檢索
GET bank/_search
{
"query": {
"match": {
"address": "mill road"
}
}
}
全文檢索按照評(píng)分進(jìn)行排序,會(huì)對(duì)檢索條件進(jìn)行分詞匹配。
查詢(xún) address 中包含 mill 或者 road 或者 mill road 的所有記錄,并給出相關(guān)性得分。
2.3 短語(yǔ)匹配 match_phase
將需要匹配的值當(dāng)成一個(gè)整體單詞 ( 不分詞 ) 進(jìn)行檢索
GET bank/_search
{
"query": {
"match_phrase": {
"address": "mill road"
}
}
}
2.4 多字段匹配 multi_match
GET bank/_search
{
"query": {
"multi_match": {
"query": "mill land",
"fields": [
"state",
"address"
]
}
}
}
multi_match 中的 query 也會(huì)進(jìn)行分詞。
查詢(xún) state 包含 mill 或 land 或者 address 包含 mill 或 land 的記錄。
2.5 復(fù)合查詢(xún) bool
復(fù)合語(yǔ)句可以合并任何其他查詢(xún)語(yǔ)句,包括復(fù)合語(yǔ)句。復(fù)合語(yǔ)句之間可以相互嵌套,可以表達(dá)復(fù)雜的邏輯。
搭配使用 must,must_not,should
must: 必須達(dá)到 must 指定的條件。 ( 影響相關(guān)性得分 )
must_not: 必須不滿足 must_not 的條件。 ( 不影響相關(guān)性得分 )
should: 如果滿足 should 條件,則可以提高得分。如果不滿足,也可以查詢(xún)出記錄。 ( 影響相關(guān)性得分 )
示例:查詢(xún)出地址包含 mill,且性別為 M,年齡不等于 28 的記錄,且優(yōu)先展示 firstname 包含 Winnie 的記錄。
GET bank/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"address": "mill"
}
},
{
"match": {
"gender": "M"
}
}
],
"must_not": [
{
"match": {
"age": "28"
}
}
],
"should": [
{
"match": {
"firstname": "Winnie"
}
}
]
}
}
}
2.6 過(guò)濾 filter
不影響相關(guān)性得分,查詢(xún)出滿足 filter 條件的記錄。
在 bool 中使用。
GET bank/_search
{
"query": {
"bool": {
"filter": {
"range": {
"age": {
"gte": 18,
"lte": 30
}
}
}
}
}
}
2.7 查詢(xún) term
匹配某個(gè)屬性的值。
全文檢索字段用 match,其他非 text 字段匹配用 term
keyword:文本精確匹配 ( 全部匹配 )
match_phase:文本短語(yǔ)匹配
規(guī)范:非 text 字段精確匹配使用 term
GET bank/_search
{
"query": {
"term": {
"age": "20"
}
}
}
2.8 聚合 aggregations
聚合提供了從數(shù)據(jù)中分組和提取數(shù)據(jù)的能力。最簡(jiǎn)單的聚合方法大致等于 SQL GROUP
BY 和 SQL 聚合函數(shù)。在 Elasticsearch 中,您有執(zhí)行搜索返回 hits(命中結(jié)果),并且同時(shí)返回聚合結(jié)果,把一個(gè)響應(yīng)中的所有 hits(命中結(jié)果)分隔開(kāi)的能力。這是非常強(qiáng)大且有效的,您可以執(zhí)行查詢(xún)和多個(gè)聚合,并且在一次使用中得到各自的(任何一個(gè)的)返回結(jié)果,使用一次簡(jiǎn)潔和簡(jiǎn)化的 API 來(lái)避免網(wǎng)絡(luò)往返。
# 聚合語(yǔ)法
"aggregations" : {
"<聚合名稱(chēng) 1>" : {
"<聚合類(lèi)型>" : {
<聚合體內(nèi)容>
}
[,"元數(shù)據(jù)" : { [<meta_data_body>] }]?
[,"aggregations" : { [<sub_aggregation>]+ }]?
}
[,"聚合名稱(chēng) 2>" : { ... }]*
}
示例 1:搜索 address 中包含 mill 的所有人的年齡分布 ( 前 10 條 ) 以及平均年齡,以及平均薪資
GET bank/_search
{
"query": {
"match": {
"address": "mill"
}
},
"aggs": {
"aggAge": {
"terms": {
"field": "age",
"size": 10
}
},
"ageAvg": {
"avg": {
"field": "age"
}
},
"balanceAvg": {
"avg": {
"field": "balance"
}
}
}
}
如果不想返回 hits 結(jié)果,可以在最后面設(shè)置 size:0
GET bank/_search
{
"query": {
"match": {
"address": "mill"
}
},
"aggs": {
"ageAggr": {
"terms": {
"field": "age",
"size": 10
}
}
},
"size": 0
}
示例 2:按照年齡聚合,并且請(qǐng)求這些年齡段的這些人的平均薪資
GET bank/_search
{
"query": {
"match_all": {}
},
"aggs": {
"age_avg": {
"terms": {
"field": "age",
"size": 1000
},
"aggs": {
"banlances_avg": {
"avg": {
"field": "balance"
}
}
}
}
},
"size": 1000
}
示例 3:查出所有年齡分布,并且這些年齡段中 M 的平均薪資和 F 的平均薪資以及這個(gè)年齡段的總體平均薪資
GET bank/_search
{
"query": {
"match_all": {}
},
"aggs": {
"age_agg": {
"terms": {
"field": "age",
"size": 100
},
"aggs": {
"gender_agg": {
"terms": {
"field": "gender.keyword",
"size": 100
},
"aggs": {
"balance_avg": {
"avg": {
"field": "balance"
}
}
}
},
"balance_avg": {
"avg": {
"field": "balance"
}
}
}
}
},
"size": 1000
}
三、Mapping
3.1 介紹
Mapping 是用來(lái)定義一個(gè)文檔 (document) ,以及它所包含的屬性 (field) 是如何存儲(chǔ)和索引的。
- 定義哪些字符串屬性應(yīng)該被看做全文本屬性 (full text fields)
- 定義哪些屬性包含數(shù)字,日期或地理位置
- 定義文檔中的所有屬性是否都能被索引 (_all 配置)
- 日期的格式
- 自定義映射規(guī)則來(lái)執(zhí)行動(dòng)態(tài)添加屬性
3.2 新版本改變
ES7 去 tpye 概念
關(guān)系型數(shù)據(jù)庫(kù)中兩個(gè)數(shù)據(jù)庫(kù)表示是獨(dú)立的,即使他們里面有相同名稱(chēng)的列也不影響使用,但 ES 中不是這樣的。elasticsearch 是基于 Lucence 開(kāi)發(fā)的搜索引擎,而 ES 中不同 type 下名稱(chēng)相同的 field 最終在 Lucence 中的處理方式是一樣的。
- 為了區(qū)分不同 type 下的同一名稱(chēng)的字段,Lucence 需要處理沖突,導(dǎo)致檢索效率下降
- 去掉type就是為了提高ES處理數(shù)據(jù)的效率。
ES7.x 版本:URL 中的 type 參數(shù)為可選。
- URL中的type參數(shù)為可選。比如,索引一個(gè)文檔不再要求提供文檔類(lèi)型。
ES8.x 版本:不支持 URL 中的 type 參數(shù)
- 不再支持URL中的type參數(shù)。
解決:將索引從多類(lèi)型遷移到單類(lèi)型,每種類(lèi)型文檔一個(gè)獨(dú)立索引
所有類(lèi)型可以參考文檔:https://www.elastic.co/guide/en/elasticsearch/reference/7.17/mapping-types.html
3.3 查詢(xún)索引的映射
GET my-index/_mapping
{
"my-index" : {
"mappings" : {
"properties" : {
"age" : {
"type" : "integer"
},
"email" : {
"type" : "keyword"
},
"name" : {
"type" : "text"
}
}
}
}
}
3.4 創(chuàng)建映射
PUT /my-index
{
"mappings": {
"properties": {
"age": {
"type": "integer"
},
"email": {
"type": "keyword"
},
"name": {
"type": "text"
}
}
}
}
#返回結(jié)果
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "my-index"
}
3.5 添加新的字段映射
PUT /my-index/_mapping
{
"properties": {
"employee-id": {
"type": "keyword",
"index": false
}
}
}
# index控制屬性值是否被索引,默認(rèn)是true。false的話就是不被索引,作為冗余存儲(chǔ)
查看添加新字段的變化
{
"my-index" : {
"mappings" : {
"properties" : {
"age" : {
"type" : "integer"
},
"email" : {
"type" : "keyword"
},
"employee-id" : {
"type" : "keyword",
"index" : false
},
"name" : {
"type" : "text"
}
}
}
}
}
3.6 更新映射
對(duì)于已經(jīng)存在的映射字段,我們不能更新。更新必須創(chuàng)建新的索引進(jìn)行數(shù)據(jù)遷移。
3.7 數(shù)據(jù)遷移
先創(chuàng)建出 newbank 的正確映射,然后使用如下方式進(jìn)行數(shù)據(jù)遷移
#創(chuàng)建新的索引
PUT /newbank
{
"mappings": {
"properties": {
"account_number": {
"type": "long"
},
"address": {
"type": "text"
},
"age": {
"type": "integer"
},
"balance": {
"type": "long"
},
"city": {
"type": "keyword"
},
"email": {
"type": "keyword"
},
"employer": {
"type": "keyword"
},
"firstname": {
"type": "text"
},
"gender": {
"type": "keyword"
},
"lastname": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"state": {
"type": "keyword"
}
}
}
}
#返回結(jié)果
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "newbank"
}
POST _reindex
{
"source": {
"index": "bank",
"type": "account"
},
"dest": {
"index": "newbank"
}
}
返回結(jié)果
#! Deprecation: [types removal] Specifying types in reindex requests is deprecated.
{
"took" : 7617,
"timed_out" : false,
"total" : 1000,
"updated" : 0,
"created" : 1000,
"deleted" : 0,
"batches" : 1,
"version_conflicts" : 0,
"noops" : 0,
"retries" : {
"bulk" : 0,
"search" : 0
},
"throttled_millis" : 0,
"requests_per_second" : -1.0,
"throttled_until_millis" : 0,
"failures" : [ ]
}
四、分詞
一個(gè) tokenizer(分詞器)接收一個(gè)字符流,將之分割為獨(dú)立的 tokens(詞元,通常是獨(dú)立的單詞),然后輸出 tokens 流。
例如 whitespace tokenizer 遇到空白字符時(shí)分割文本,它會(huì)將文本 “Quick brown fox!” 分割為 Quick,brown,fox!。
該 tokenizer(分詞器)還負(fù)責(zé)記錄各個(gè) term(詞條)的順序或 position 位置(用于 phrase 短語(yǔ)和 word proximity 詞近鄰查詢(xún)),以及 term(詞條)所代表的原始 word(單詞)的 start(起始)和 end(結(jié)束)的 character offsets(字符偏移量)(用于高亮顯示搜索的內(nèi)容)。
Elasticsearch 提供了很多內(nèi)置的分詞器,可以用來(lái)構(gòu)建 custom analyzers(自定義分詞器)。
4.1 安裝 ik 分詞器
注意:不能用默認(rèn) elasticsearch-plugin install xxx.zip 進(jìn)行自動(dòng)安裝
1.進(jìn)入elasticsearch 插件掛載
cd /mydata/elasticsearch/plugins
2.創(chuàng)建 ik 目錄
mkdir ik
3.進(jìn)入 ik 目錄
cd ik
4.下載 ik 分詞器
wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip
5.下載成功
[root@localhost ik]# wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip
--2023-05-09 16:49:36-- https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip
正在解析主機(jī) github.com (github.com)... 20.205.243.166
正在連接 github.com (github.com)|20.205.243.166|:443... 已連接。
已發(fā)出 HTTP 請(qǐng)求,正在等待回應(yīng)... 302 Found
位置:https://objects.githubusercontent.com/github-production-release-asset-2e65be/2993595/19827980-fef3-11e9-8cda-384bc0d9396c?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230509%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230509T084937Z&X-Amz-Expires=300&X-Amz-Signature=dede12056de2e09b1386e24e2db04835a7283f829d4e35f4ce0d268b9fa36780&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=2993595&response-content-disposition=attachment%3B%20filename%3Delasticsearch-analysis-ik-7.4.2.zip&response-content-type=application%2Foctet-stream [跟隨至新的 URL]
--2023-05-09 16:49:37-- https://objects.githubusercontent.com/github-production-release-asset-2e65be/2993595/19827980-fef3-11e9-8cda-384bc0d9396c?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230509%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230509T084937Z&X-Amz-Expires=300&X-Amz-Signature=dede12056de2e09b1386e24e2db04835a7283f829d4e35f4ce0d268b9fa36780&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=2993595&response-content-disposition=attachment%3B%20filename%3Delasticsearch-analysis-ik-7.4.2.zip&response-content-type=application%2Foctet-stream
正在解析主機(jī) objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.109.133, 185.199.108.133, 185.199.110.133, ...
正在連接 objects.githubusercontent.com (objects.githubusercontent.com)|185.199.109.133|:443... 已連接。
已發(fā)出 HTTP 請(qǐng)求,正在等待回應(yīng)... 200 OK
長(zhǎng)度:4504487 (4.3M) [application/octet-stream]
正在保存至: “elasticsearch-analysis-ik-7.4.2.zip”
100%[=========================================================================================================================================================================>] 4,504,487 1.44MB/s 用時(shí) 3.0s
2023-05-09 16:49:41 (1.44 MB/s) - 已保存 “elasticsearch-analysis-ik-7.4.2.zip” [4504487/4504487])
6.下載成功后解壓到 ik 目錄
unzip elasticsearch-analysis-ik-7.4.2.zip
7.修改 ik 目錄讀寫(xiě)權(quán)限
chmod -R 777 ik/
8.進(jìn)入 docker 的 bash 控制臺(tái)
docker exec -it elasticsearch /bin/bash
9.進(jìn)入 elasticsearch 的 bin 執(zhí)行如下命令
[root@21fddd211b43 bin]# elasticsearch-plugin list
ik
出現(xiàn) ik 表明安裝完成
4.2 測(cè)試分詞器
1.Kibana 使用 ik_smart 檢索
4.3 自定義詞庫(kù)
ik 分詞器沒(méi)辦法識(shí)別新的詞匯和網(wǎng)絡(luò)用語(yǔ),所以需要我們自己自定義詞庫(kù)來(lái)達(dá)到擴(kuò)展詞庫(kù)的目的。
1.修改配置文件
ik 分詞器的配置文件在容器中的路徑:
/usr/share/elasticsearch/plugins/ik/config/IKAnalyzer.cfg.xml。
修改這個(gè)文件可以通過(guò)修改映射文件,文件路徑:
/mydata/elasticsearch/plugins/ik/config/IKAnalyzer.cfg.xml
編輯配置文件:
vim /mydata/elasticsearch/plugins/ik/config/IKAnalyzer.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 擴(kuò)展配置</comment>
<!--用戶可以在這里配置自己的擴(kuò)展字典 -->
<entry key="ext_dict"></entry>
<!--用戶可以在這里配置自己的擴(kuò)展停止詞字典-->
<entry key="ext_stopwords"></entry>
<!--用戶可以在這里配置遠(yuǎn)程擴(kuò)展字典 -->
<entry key="remote_ext_dict">http://192.168.57.129/es/fenci.txt</entry>
<!--用戶可以在這里配置遠(yuǎn)程擴(kuò)展停止詞字典-->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
修改配置 remote_ext_dict 的屬性值,指定一個(gè) 遠(yuǎn)程網(wǎng)站文件的路徑,比如 http://www.xxx.com/ikwords.text。
這里我們可以自己搭建一套 nginx 環(huán)境,然后把 ikwords.text 放到 nginx 根目錄。
修改 IKAnalyzer.cfg.xml 后重啟 elasticsearch
docker restart elasticsearch
訪問(wèn) Kibana 如下圖
五、附錄-安裝 nginx
5.1 安裝步驟
1.在 /mydata 目錄下創(chuàng)建 nginx 目錄
mkdir nginx
2.進(jìn)入 nginx 目錄安裝 nginx
[root@localhost mydata]# docker run -p 80:80 --name nginx -d nginx:1.10
Unable to find image 'nginx:1.10' locally
1.10: Pulling from library/nginx
6d827a3ef358: Pull complete
1e3e18a64ea9: Pull complete
556c62bb43ac: Pull complete
Digest: sha256:6202beb06ea61f44179e02ca965e8e13b961d12640101fca213efbfd145d7575
Status: Downloaded newer image for nginx:1.10
4026fb105bd2a0905512b553bcea6452eacb55b2c4499ceef4a148c6023f60c9
3.將容器內(nèi)的配置文件拷貝到 nginx 目錄別忘了后面的點(diǎn)
docker container cp nginx:/etc/nginx .
4.修改文件名稱(chēng)
mv nginx conf
5.把這個(gè) conf 移動(dòng)到 /mydata/nginx 下
mv conf/ nginx
6.終止原容器
docker stop nginx
7.執(zhí)行命令刪除原容器
docker rm nginx
8.創(chuàng)建新的 nginx
docker run -p 80:80 --name nginx \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/logs:/var/log/nginx \
-v /mydata/nginx/conf:/etc/nginx \
-d nginx:1.10
9.給 nginx 的 html 下面放的所有資源可以直接訪問(wèn)
vi index.html
10.編寫(xiě) html
<h1>Gulimall</h1>
11.安裝成功,訪問(wèn)效果如下圖
5.2 創(chuàng)建分析文本
1.html 目錄下創(chuàng)建 es 目錄,在 es 目錄下創(chuàng)建文本
mkdir es
cd es
vi fenci.txt
尚硅谷
喬碧蘿
編寫(xiě)文本,esc 后 shift + : wq 保存退出。訪問(wèn)如下圖文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-435128.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-435128.html
到了這里,關(guān)于全文檢索-Elasticsearch-進(jìn)階檢索的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!