理想國Elasticsearch入門教程
技術標籤:JavaElasticsearch大資料
01.簡介
what:是什麼
- 全文搜尋引擎技術
- 支援PB級的快速搜尋
- Elaticsearch,簡稱為es, es是一個開源的高擴充套件的分散式全文檢索引擎,它可以近乎實時的檢索資料;本身擴充套件性很好,可以擴充套件到上百臺伺服器,處理PB級別的資料。ES使用Java開發。Lucene作為其核心來實現所有索引和搜尋的功能,但是它的目的是通過簡單的RESTful API來隱藏Lucene的複雜性,從而讓全文搜尋變得簡單。
why:為什麼使用
- 非常流行,且免費開源
where:在哪裡用
- 大部分Web專案都可以用
when:什麼時候用
- 當需要做搜尋的時候
how:如何使用
- 看下文
02.Elasticsearch的使用案例
- 百度:百度目前廣泛使用Elasticsearch作為文字資料分析,採集百度所有伺服器上的各類指標資料及使用者自定義資料,通過對各種資料進行多維分析展示,輔助定位分析例項異常或業務層面異常。目前覆蓋百度內部20多個業務線(包括casio、雲分析、網盟、預測、文庫、直達號、錢包、風控等),單叢集最大100臺機器,200個ES節點,每天匯入30TB+資料
- 新浪使用ES 分析處理32億條實時日誌
- 阿里使用ES 構建挖財自己的日誌採集和分析體系
- 2013年初,GitHub拋棄了Solr,採用Elasticsearch 來做PB級的搜尋。 “GitHub使用Elasticsearch搜尋20TB的資料,包括13億檔案和1300億行程式碼”
- 維基百科:啟動以Elasticsearch為基礎的核心搜尋架構
- SoundCloud:“SoundCloud使用Elasticsearch為1.8億使用者提供即時而精準的音樂搜尋服務”
03.Elasticsearch安裝
下載ES壓縮包
- 目前Elasticsearch最新的版本是7.4.2,我們使用6.8.0版本,建議使用JDK1.8及以上
- Elasticsearch分為Linux和Window版本,基於我們主要學習的是Elasticsearch的Java客戶端的使用,所以我們課程中使用的是安裝較為簡便的Window版本,專案上線後,公司的運維人員會安裝Linux版的ES供我們連線使用。
- Elasticsearch的官方地址:https://www.elastic.co/cn/downloads/past-releases
- 在資料中已經提供了下載好的6.8.0的壓縮包
安裝ES服務
- Window版的Elasticsearch的安裝很簡單,類似Window版的Tomcat
- 解壓開即安裝完畢
- 修改:jvm.options
-Xms256m
-Xmx256m
啟動ES服務
- 點選Elasticsearch下的bin目錄下的Elasticsearch.bat啟動
訪問ES服務
- 注意:9300是tcp通訊埠,叢集間和TCP 客戶端都執行該埠,9200是http協議的RESTful介面
- 通過瀏覽器訪問Elasticsearch伺服器,看到如下返回的json資訊,代表服務啟動成功
04.安裝Kibana
什麼是Kibana
- Kibana是ElasticSearch的資料視覺化和實時分析的工具,利用Elasticsearch的聚合功能,生成各種圖表,如柱形圖,線狀圖,餅圖等。
下載
- https://www.elastic.co/cn/products/kibana
安裝
- 解壓即可
配置
- 進入安裝目錄下的config目錄的kibana.yml檔案
- 修改elasticsearch伺服器的地址:
elasticsearch.hosts: ["http://localhost:9200"]
- 修改kibana配置支援中文:
i18n.locale: "zh-CN"
啟動
- kibana.bat
訪問
- http://localhost:5601/app/kibana
05.安裝Postman
what:是什麼
- Postman中文版是Postman這款強大網頁除錯工具的windows客戶端,提供功能強大的Web API 和 HTTP 請求除錯。
- 軟體功能強大,介面簡潔明晰、操作方便快捷,設計得很人性化。
- Postman中文版能夠傳送任何型別的HTTP 請求 (GET, HEAD, POST, PUT…),不僅能夠表單提交,且可以附帶任意型別請求體。
下載Postman工具
- Postman官網:https://www.getpostman.com
安裝
- 一直下一步就行
06.整合IK分詞器
what:是什麼
- Lucene的IK分詞器早在2012年已經沒有維護了,現在我們要使用的是在其基礎上維護升級的版本,並且開發為Elasticsearch的整合外掛了,與Elasticsearch一起維護升級,版本也保持一致。
- GitHub倉庫地址:https://github.com/medcl/elasticsearch-analysis-ik
安裝外掛
- 解壓之後,存放到elasticsearch的plugins目錄中,即可安裝成功外掛。
- 注意:解壓的時候,如下檔案必須在plugins目錄的第一級目錄下
- 重新啟動ElasticSearch
測試:IK分詞器有兩種分詞模式:ik_max_word和ik_smart模式。
- ik_max_word:會將文字做最細粒度的拆分
- ik_smart:會做最粗粒度的拆分,智慧拆分
請求方式:POST
請求url:http://127.0.0.1:9200/_analyze
請求體:
{
"analyzer": "ik_smart",
"text": "南京市長江大橋"
}
新增擴充套件詞典和停用詞典
- 停用詞
- 有些詞在文字中出現的頻率非常高。但對本文的語義產生不了多大的影響。
- 例如英文的a、an、the、of等。或中文的”的、了、呢等”。
- 這樣的詞稱為停用詞。停用詞經常被過濾掉,不會被進行索引。
- 在檢索的過程中,如果使用者的查詢詞中含有停用詞,系統會自動過濾掉。
- 停用詞可以加快索引的速度,減少索引庫檔案的大小。
- 擴充套件詞
- 就是不想讓哪些詞被分開,讓他們分成一個詞。
- 比如上面的江大橋
自定義擴充套件詞庫
- 進入到plugins\elasticsearch-analysis-ik-6.8.0\config目錄下, 新增自定義詞典myext_dict.dic,輸入“江大橋”
- 將我們自定義的擴充套件詞典檔案,配置到IKAnalyzer.cfg.xml檔案中
<entry key="ext_dict">myext_dict.dic</entry>
- 然後重啟ES
- 重寫進行測試
請求方式:POST
請求url:http://127.0.0.1:9200/_analyze
請求體:
{
"analyzer": "ik_smart",
"text": "南京市長江大橋"
}
07.ES核心概念
what:是什麼
- Elasticsearch是面向文件(document oriented)的,這意味著它可以儲存整個物件或文件(document)。
- 然而它不僅僅是儲存,還會索引(index)每個文件的內容使之可以被搜尋。
- 在Elasticsearch中,你可以對文件(而非成行成列的資料)進行索引、搜尋、排序、過濾。
- Elasticsearch比傳統關係型資料庫如下:
索引庫(indexes)------------->資料庫(Databases)
型別(type)------------------>資料表(Table)
文件(Document)-------------->行(Row)
欄位(Field)----------------->列(Columns)
對映(mappings)-------------->DDL建立資料庫表的語句
詳細說明:
概念 | 說明 |
---|---|
索引庫(indexes) | 索引庫包含一堆相關業務,結構相似的文件document資料,比如說建立一個商品product索引庫,裡面可能就存放了所有的商品資料。 |
型別(type) | type是索引庫中的一個邏輯資料分類,一個type下的document,都有相同的field,類似於資料庫中的表。比如商品type,裡面存放了所有的商品document資料。6.0版本以後一個index只能有1個type,6.0版本以前每個index裡可以是一個或多個type。7.0以後,沒有type這個概念了 |
文件(document) | 文件是es中的存入索引庫最小資料單元,一個document可以是一條客戶資料,一條商品資料,一條訂單資料,通常用JSON資料結構表示。document存在索引庫下的type型別中。 |
欄位(field) | Field是Elasticsearch的最小單位。一個document裡面有多個field,每個field就是一個數據欄位 |
對映配置(mappings) | 對type文件結構的約束叫做對映(mapping) ,用來定義document的每個欄位的約束。如:欄位的資料型別、是否分詞、是否索引、是否儲存等特性。type是模擬mysql中的table概念。表是有結構的,也就是表中每個欄位都有約束資訊; |
08.ES基本操作
通過http://localhost:5601/app/kibana進入開發工具,輸入以下程式碼進行測試
# 新增索引
PUT /lxgzhw
PUT /lxgzhw01
# 檢視索引
GET /lxgzhw
GET /lxgzhw01
# 刪除索引
DELETE /lxgzhw
09.型別(type)及對映(mapping)操作
what:是什麼
- 有了
索引庫
,等於有了資料庫中的database
。 - 接下來就需要索引庫中的
型別
了,也就是資料庫中的表
。 - 建立資料庫表需要設定欄位約束,索引庫也一樣,在建立索引庫的型別時,需要知道這個型別下有哪些欄位,每個欄位有哪些約束資訊,這就叫做
對映(mapping)
10.配置對映
給lxgzhw這個索引庫添加了一個名為goods
的型別,並且在型別中設定了4個欄位:
- title:商品標題
- subtitle: 商品子標題
- images:商品圖片
- price:商品價格
傳送請求:
PUT /lxgzhw/goods/_mapping
{
"properties": {
"title":{
"type": "text",
"analyzer": "ik_max_word"
},
"subtitle":{
"type": "text",
"analyzer": "ik_max_word"
},
"images":{
"type": "keyword",
"index": false
},
"price":{
"type": "float",
"index": true
}
}
}
響應結果:
{
"acknowledged" : true
}
內容解釋:
PUT /索引庫名/_mapping/型別名稱 或 索引庫名/型別名稱/_mapping
{
"properties": {
"欄位名稱":{
"type【型別】": "型別",
"index【是否索引】": true,
"store【是否儲存】": true,
"analyzer【分析器】": "分詞器"
}
...
}
}
型別名稱:就是前面將的type的概念,類似於資料庫中的表
欄位名:任意填寫,下面指定許多屬性,例如:
- type:型別,Elasticsearch中支援的資料型別非常豐富,說幾個關鍵的:
- String型別,又分兩種:
- text:可分詞
- keyword:不可分詞,資料會作為完整欄位進行匹配
- Numerical:數值型別,分兩類
- 基本資料型別:long、interger、short、byte、double、float、half_float
- 浮點數的高精度型別:scaled_float
- Date:日期型別
- Array:陣列型別
- Object:物件
- String型別,又分兩種:
- index:是否索引,預設為true,也就是說你不進行任何配置,所有欄位都會被索引。
- true:欄位會被索引,則可以用來進行搜尋。預設值就是true
- false:欄位不會被索引,不能用來搜尋
- store:是否將資料進行獨立儲存,預設為false
- 原始的文字會儲存在
_source
裡面,預設情況下其他提取出來的欄位都不是獨立儲存的,是從_source
裡面提取出來的。 - 當然你也可以獨立的儲存某個欄位,只要設定store:true即可,獲取獨立儲存的欄位要比從_source中解析快得多,但是也會佔用更多的空間,所以要根據實際業務需求來設定,預設為false。
- 原始的文字會儲存在
- analyzer:分詞器,這裡的
ik_max_word
即使用ik分詞器
11.檢視對映
傳送請求:
# 檢視對映
GET /lxgzhw/goods/_mapping
響應結果:
{
"lxgzhw" : {
"mappings" : {
"goods" : {
"properties" : {
"images" : {
"type" : "keyword",
"index" : false
},
"price" : {
"type" : "float"
},
"subtitle" : {
"type" : "text",
"analyzer" : "ik_max_word"
},
"title" : {
"type" : "text",
"analyzer" : "ik_max_word"
}
}
}
}
}
}
12.一次建立索引庫及配置對映(常用)
剛才的案例中,我們是把建立索引庫和型別分開來做,其實也可以在建立索引庫的同時,直接制定索引庫中的型別
傳送請求:
# 一次建立索引庫及配置對映
PUT /lxgzhw01
{
"settings": {},
"mappings": {
"goods":{
"properties": {
"title":{
"type": "text",
"analyzer": "ik_max_word"
},
"subtitle":{
"type": "text",
"analyzer": "ik_max_word"
},
"images":{
"type": "keyword",
"index": false
},
"price":{
"type": "float",
"index": true
}
}
}
}
}
響應結果:
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "lxgzhw01"
}
請求內容解釋:
PUT /{索引庫名稱}
{
"settings【設定】": {},
"mappings【對映】": {
"{型別名稱}":{
"properties": {
"title":{
"type【型別】": "text",
"index【是否索引】": true,
"store【是否儲存】": true,
"analyzer【分析器】": "ik_max_word"
}
...
}
}
}
}
13.文件操作
what:是什麼
- 文件,即索引庫中某個型別下的資料,會根據規則建立索引,將來用來搜尋。
可以類比做資料庫中的每一行資料。
14.新增文件
傳送請求:
# 新增文件
POST /lxgzhw/goods
{
"title":"小米手機",
"images":"http://image.aishop.com/12479122.jpg",
"price":2699.00
}
響應結果:
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "EwVLY24BL4R5dXuhZ--1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
響應結果解析:
{
"_index【索引庫】" : "lxgzhw",
"_type【型別】" : "goods",
"_id【主鍵id】" : "EwVLY24BL4R5dXuhZ--1",
"_version【版本】" : 1,
"result【操作結果】" : "created",
"_shards【分片】" : {
"total【總數】" : 2,
"successful【成功】" : 1,
"failed【失敗】" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
- 可以看到結果顯示為:
created
,是建立成功了。 - 另外,需要注意的是,在響應結果中有個
_id
欄位,這個就是這條文件資料的唯一標示
,以後的增刪改查都依賴這個id作為唯一標示。 - 可以看到id的值為:EwVLY24BL4R5dXuhZ–1,這裡我們新增時沒有指定id,所以是ES幫我們隨機生成的id。
15.檢視文件
根據rest風格,新增是put,查詢是get(post也可以用來做查詢),不過查詢一般都需要條件,這裡我們把剛剛生成資料的id帶上。
傳送請求:
GET /lxgzhw/goods/EwVLY24BL4R5dXuhZ--1
響應結果:
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "EwVLY24BL4R5dXuhZ--1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"title" : "小米手機",
"images" : "http://image.aishop.com/12479122.jpg",
"price" : 2699.0
}
}
響應結果解析:
{
"_index【索引庫】" : "lxgzhw",
"_type【型別】" : "goods",
"_id【主鍵id】" : "EwVLY24BL4R5dXuhZ--1",
"_version【版本】" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found【查詢結果】" : true,
"_source【源文件資訊】" : {
"title" : "小米手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 2699.0
}
}
_source
:源文件資訊,所有的資料都在裡面。_id
:這條文件的唯一標示- found:查詢結果,返回true代表查到,false代表沒有
16.自定義id新增文件
傳送請求:
# 自定義id新增文件
POST /lxgzhw/goods/1
{
"title":"小米手機",
"images":"http://image.leyou.com/12479122.jpg",
"price":2699.00
}
響應結果:
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
主鍵id變為指定的id
請求內容解析:
POST /lxgzhw/goods/{自定義註解id}
{
"title":"小米手機",
"images":"http://image.leyou.com/12479122.jpg",
"price":2699.00
}
17.修改文件
新增時,主鍵不變則會將原有內容覆蓋。
傳送請求:
# 修改文件
POST /lxgzhw/goods/1
{
"title":"超米手機",
"images":"http://image.leyou.com/12479122.jpg",
"price":3899.00
}
響應結果:
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "1",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1
}
- 可以看到result結果是:
updated
,顯然是更新資料
18.刪除文件
刪除一條
- 刪除一個文件也不會立即從磁碟上移除,它只是被標記成已刪除。
- Elasticsearch將會在你之後新增更多索引的時候才會在後臺進行刪除內容的清理。
傳送請求:
# 刪除文件
DELETE /lxgzhw/goods/1
響應結果:
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "1",
"_version" : 3,
"result" : "deleted",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 1
}
- 可以看到result結果是:deleted,資料被刪除。如果刪除不存在的問題,result:not_found
19.根據條件刪除
傳送請求:
# 根據條件刪除
POST /lxgzhw/_delete_by_query
{
"query":{
"match":{
"title":"小米"
}
}
}
響應結果:
{
"took" : 58,
"timed_out" : false,
"total" : 2,
"deleted" : 2,
"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" : [ ]
}
響應結果解析:
{
"took【耗時】" : 58,
"timed_out" : false,
"total【總數】" : 2,
"deleted【刪除總數】" : 2,
"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" : [ ]
}
20.傳送請求批量操作_bulk
Bulk 操作是將文件的增刪改查一些列操作,通過一次請求全都做完。減少網路傳輸次數。相當於,將多個新增、修改、刪除的請求寫到一次請求當中。
注意:bulk的請求體與其他的請求體稍有不同!
請求語法:
POST /lxgzhw/goods/_bulk
{ action: { metadata }}\n
{ request body }\n
{ action: { metadata }}\n
{ request body }\n
...
語法解析:
- 每行一定要以換行符(\n)結尾,包括最後一行
- action/metadata 部分,指定做什麼操作
- action代表操作的動作,必須是如下的動作之一
- create:如果文件不存在,那麼就建立
- index:建立一個新的文件或者替換現有文件
- update:部分更新文件
- delete:刪除一個文件,這種操作不帶請求體
- metadata,是文件的元資料,包括索引(
_index
),型別(_type
),id(_id
)…等
- action代表操作的動作,必須是如下的動作之一
- request body 請求體,正常的新增文件的請求體內容(注意,不要帶換行符)
隔離:每個操作互不影響。操作失敗的行會返回其失敗資訊。
實際用法:bulk請求一次不要太大,否則積壓到記憶體中,效能會下降。所以,一次請求幾千個操作、大小控制在5M-15M之間正好。
傳送請求:
# 傳送請求批量操作_bulk
POST /lxgzhw/goods/_bulk
{"index":{"_index" : "lxgzhw","_type" : "goods"}}
{"title":"大米手機","images":"http://image.leyou.com/12479122.jpg","price":3288}
{"index":{"_index" : "lxgzhw","_type" : "goods"}}
{"title":"小米手機","images":"http://image.leyou.com/12479122.jpg","price":2699}
{"index":{"_index" : "lxgzhw","_type" : "goods"}}
{"title":"小米電視4A","images":"http://image.leyou.com/12479122.jpg","price":4288}
{"index":{"_index" : "lxgzhw","_type" : "goods"}}
{"title": "華為手機","images": "http://image.leyou.com/12479122.jpg","price": 5288,"subtitle": "小米"}
{"index":{"_index" : "lxgzhw","_type" : "goods"}}
{"title":"apple手機","images":"http://image.leyou.com/12479122.jpg","price":5899.00}
注意:
- 請求體的內容不要換行
- 請注意 delete 動作不能有請求體
- 謹記最後一個換行符不要落下。
響應結果:
{
"took" : 41,
"errors" : false,
"items" : [
{
"index" : {
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "FFTEhm4BO0vjk-su75eC",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1,
"status" : 201
}
}
...
]
}
- 每個子請求都是獨立執行,因此某個子請求的失敗不會對其他子請求的成功與否造成影響。
- 如果其中任何子請求失敗,最頂層的 error 標誌被設定為 true ,並且在相應的請求報告出錯誤明細。
- status屬性:代表響應狀態碼
21.請求體查詢
what:是什麼
- Elasticsearch提供了一個基於JSON的,在請求體內編寫查詢語句的查詢方式。稱之為請求體查詢。
- Elasticsearch 使用它以簡單的 JSON介面來展現 Lucene 功能的絕大部分。
- 這種查詢語言相對於使用晦澀難懂的查詢字串的方式,更靈活、更精確、易讀和易除錯。
- 這種查詢還有一種稱呼:Query DSL (Query Domain Specific Language),領域特定語言。
22.查詢所有(match_all)
傳送請求:
# 查詢所有
POST /lxgzhw/_search
{
"query": {
"match_all": {}
}
}
請求內容解析:
請求方法:POST
請求地址:http://127.0.0.1:9200/索引庫名/_search
POST /{索引庫}/_search
{
"query":{
"查詢型別":{
"查詢條件":"查詢條件值"
}
}
}
這裡的query代表一個查詢物件,裡面可以有不同的查詢屬性
- 查詢型別:
- 例如:
match_all(代表查詢所有)
,match
,term
,range
等等
- 例如:
- 查詢條件:查詢條件會根據型別的不同,寫法也有差異
響應結果
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 3,
"max_score" : 1.0,
"hits" : [
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "ADWoZ24Bx8DA1HO-R9DD",
"_score" : 1.0,
"_source" : {
"title" : "小米電視4A",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 4288
}
},
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_zWoZ24Bx8DA1HO-R8_D",
"_score" : 1.0,
"_source" : {
"title" : "小米手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 2699
}
},
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_jWoZ24Bx8DA1HO-R8_D",
"_score" : 1.0,
"_source" : {
"title" : "大米手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 3288
}}]}}
響應結果解析:
{
"took【查詢花費時間,單位毫秒】" : 1,
"timed_out【是否超時】" : false,
"_shards【分片資訊】" : {
"total【總數】" : 5,
"successful【成功】" : 5,
"skipped【忽略】" : 0,
"failed【失敗】" : 0
},
"hits【搜尋命中結果】" : {
"total【命中總數】" : 3,
"max_score【所有查詢結果中,文件的最高得分】" : 1.0,
"hits【命中結果集合】" : [
{
"_index【索引庫】" : "heima",
"_type【型別】" : "goods",
"_id【主鍵】" : "ADWoZ24Bx8DA1HO-R9DD",
"_score【當前結果匹配得分】" : 1.0,
"_source【源文件資訊】" : {
"title" : "小米電視4A",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 4288
}
}...}]}}
23.匹配查詢(match)
match
型別查詢,會把查詢條件進行分詞,然後進行查詢,多個詞條之間是or的關係
傳送請求:
# 匹配查詢
POST /lxgzhw/_search
{
"query": {
"match": {
"title": "小米手機"
}
}
}
響應結果:
{
"took" : 5,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 3,
"max_score" : 0.5753642,
"hits" : [
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_zWoZ24Bx8DA1HO-R8_D",
"_score" : 0.5753642,
"_source" : {
"title" : "小米手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 2699
}
},
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "ADWoZ24Bx8DA1HO-R9DD",
"_score" : 0.2876821,
"_source" : {
"title" : "小米電視4A",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 4288
}
},
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_jWoZ24Bx8DA1HO-R8_D",
"_score" : 0.2876821,
"_source" : {
"title" : "大米手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 3288
}
}
]
}
}
在上面的案例中,不僅會查詢到電視,而且與小米相關的都會查詢到。某些情況下,我們需要更精確查詢,我們希望這個關係變成and
,可以這樣做:
傳送請求:
本例中,只有同時包含小米
和手機
的詞條才會被搜尋到。
POST /lxgzhw/_search
{
"query": {
"match": {
"title": {
"query": "小米手機",
"operator": "and"
}
}
}
}
響應結果:
{
"took" : 4,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.5753642,
"hits" : [
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_zWoZ24Bx8DA1HO-R8_D",
"_score" : 0.5753642,
"_source" : {
"title" : "小米手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 2699
}
}
]
}
}
24.多欄位匹配查詢(multi_match)
multi_match
與match
類似,不同的是它可以在多個欄位中查詢。
傳送請求:
本例中,我們在title欄位和subtitle欄位中查詢小米
這個詞
POST /lxgzhw/_search
{
"query": {
"multi_match": {
"query": "小米",
"fields": ["title","subtitle"]
}
}
}
fields屬性:設定查詢的多個欄位
響應結果:
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 3,
"max_score": 0.6099695,
"hits": [
{
"_index": "lxgzhw",
"_type": "goods",
"_id": "qfHnLG4BWrjRrOzL8Ywa",
"_score": 0.6099695,
"_source": {
"title": "小米電視4A",
"images": "http://image.leyou.com/12479122.jpg",
"price": 4288
}
},
{
"_index": "lxgzhw",
"_type": "goods",
"_id": "qvHyLG4BWrjRrOzL9Yzn",
"_score": 0.2876821,
"_source": {
"title": "華為手機",
"images": "http://image.leyou.com/12479122.jpg",
"price": 5288,
"subtitle": "小米"
}
},
{
"_index": "lxgzhw",
"_type": "goods",
"_id": "qPHnLG4BWrjRrOzL3Yxl",
"_score": 0.2876821,
"_source": {
"title": "小米手機",
"images": "http://image.leyou.com/12479122.jpg",
"price": 2699
}
}
]
}
}
25.關鍵詞精確查詢(term)
term查詢,精確的關鍵詞匹配查詢,不物件查詢條件進行分詞
傳送請求:
POST /lxgzhw/_search
{
"query": {
"term": {
"title": {
"value": "小米"
}
}
}
}
響應結果:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 0.6931472,
"hits" : [
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "CzXDZ24Bx8DA1HO-nNDZ",
"_score" : 0.6931472,
"_source" : {
"title" : "小米手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 2699
}
},
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "DDXDZ24Bx8DA1HO-nNDZ",
"_score" : 0.2876821,
"_source" : {
"title" : "小米電視4A",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 4288
}
}
]
}
}
26.多關鍵詞精確查詢(terms)
terms
查詢和 term 查詢一樣,但它允許你指定多值進行匹配。如果這個欄位包含了指定值中的任何一個值,那麼這個文件滿足條件,類似於mysql的in:
傳送請求:
查詢價格為2699或4288的商品
POST /lxgzhw/_search
{
"query": {
"terms": {
"price": [2699,4288]
}
}
}
響應結果:
{
"took" : 26,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 1.0,
"hits" : [
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_l0-iHYBYIdsgnOgtk2r",
"_score" : 1.0,
"_source" : {
"title" : "小米電視4A",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 4288
}
},
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_V0-iHYBYIdsgnOgtk2r",
"_score" : 1.0,
"_source" : {
"title" : "小米手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 2699
}
}
]
}
}
17.結果過濾
預設情況下,elasticsearch在搜尋的結果中,會把文件中儲存在_source
的所有欄位都返回。如果我們只想獲取其中的部分欄位,我們可以新增_source
的過濾
指定欄位
- 指定查詢結果中,只顯示title和price兩個欄位
傳送請求:
POST /lxgzhw/_search
{
"_source": ["title","price"],
"query": {
"term": {
"price": 2699
}
}
}
響應結果:
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_V0-iHYBYIdsgnOgtk2r",
"_score" : 1.0,
"_source" : {
"price" : 2699,
"title" : "小米手機"
}
}
]
}
}
過濾指定欄位:includes和excludes
- includes:來指定想要顯示的欄位
- excludes:來指定不想要顯示的欄位
傳送請求:
POST /lxgzhw/_search
{
"_source": {
"includes":["title","price"]
},
"query": {
"term": {
"price": 2699
}
}
}
響應結果
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_V0-iHYBYIdsgnOgtk2r",
"_score" : 1.0,
"_source" : {
"price" : 2699,
"title" : "小米手機"
}
}
]
}
}
POST /lxgzhw/_search
{
"_source": {
"excludes": ["images"]
},
"query": {
"term": {
"price": 2699
}
}
}
響應結果
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_V0-iHYBYIdsgnOgtk2r",
"_score" : 1.0,
"_source" : {
"price" : 2699,
"title" : "小米手機"
}
}
]
}
}
18.布林組合(bool)
bool
把各種其它查詢通過must
(必須 )、must_not
(必須不)、should
(應該)的方式進行組合
傳送請求:
POST /lxgzhw/_search
{
"query":{
"bool":{
"must": { "match": { "title": "小米" }},
"must_not": { "match": { "title": "電視" }},
"should": { "match": { "title": "手機" }}
}
}
}
響應結果:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.87546873,
"hits" : [
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_V0-iHYBYIdsgnOgtk2r",
"_score" : 0.87546873,
"_source" : {
"title" : "小米手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 2699
}
}
]
}
}
19.範圍查詢(range)
range
查詢找出那些落在指定區間內的數字或者時間。range
查詢允許以下字元:
操作符 | 說明 |
---|---|
gt == (greater than) | 大於> |
gte == (greater than equal) | 大於等於>= |
lt == (less than) | 小於< |
lte == (less than equal) | 小於等於<= |
傳送請求:查詢價格大於等於2699,且小於4000元的所有商品。
POST /lxgzhw/_search
{
"query": {
"range": {
"price": {"gte": 2699,"lt": 4000}
}
}
}
響應結果:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 3,
"max_score" : 1.0,
"hits" : [
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"title" : "超米手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 3899.0
}
},
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_F0-iHYBYIdsgnOgtk2r",
"_score" : 1.0,
"_source" : {
"title" : "大米手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 3288
}
},
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_V0-iHYBYIdsgnOgtk2r",
"_score" : 1.0,
"_source" : {
"title" : "小米手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 2699
}
}
]
}
}
20.模糊查詢(fuzzy)
fuzzy自動將拼寫錯誤的搜尋文字,進行糾正,糾正以後去嘗試匹配索引中的資料。它允許使用者搜尋詞條與實際詞條出現偏差,但是偏差的編輯距離不得超過2:
傳送請求:如下查詢,也能查詢到apple手機
POST /lxgzhw/_search
{
"query": {
"fuzzy": {
"title": "appla"
}
}
}
響應結果:
{
"took" : 17,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.23014566,
"hits" : [
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "AF0-iHYBYIdsgnOgtk6r",
"_score" : 0.23014566,
"_source" : {
"title" : "apple手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 5899.0
}
}
]
}
}
修改偏差值:你搜索關鍵詞的偏差,預設就是2,我們可以通過fuzziness修改。
POST /lxgzhw/_search
{
"query": {
"fuzzy": {
"title": {
"value": "applaa",
"fuzziness": 2
}
}
}
}
21.單欄位排序
sort
可以讓我們按照不同的欄位進行排序,並且通過order
指定排序的方式。desc降序,asc升序。
傳送請求:
POST /lxgzhw/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"price": {"order": "desc"}
}
]
}
響應結果:
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 6,
"max_score" : null,
"hits" : [
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "AF0-iHYBYIdsgnOgtk6r",
"_score" : null,
"_source" : {
"title" : "apple手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 5899.0
},
"sort" : [
5899.0
]
},
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_10-iHYBYIdsgnOgtk2r",
"_score" : null,
"_source" : {
"title" : "華為手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 5288,
"subtitle" : "小米"
},
"sort" : [
5288.0
]
},
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_l0-iHYBYIdsgnOgtk2r",
"_score" : null,
"_source" : {
"title" : "小米電視4A",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 4288
},
"sort" : [
4288.0
]
},
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "1",
"_score" : null,
"_source" : {
"title" : "超米手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 3899.0
},
"sort" : [
3899.0
]
},
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_F0-iHYBYIdsgnOgtk2r",
"_score" : null,
"_source" : {
"title" : "大米手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 3288
},
"sort" : [
3288.0
]
},
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_V0-iHYBYIdsgnOgtk2r",
"_score" : null,
"_source" : {
"title" : "小米手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 2699
},
"sort" : [
2699.0
]
}
]
}
}
22.多欄位排序
假定我們想要結合使用 price和 _score(得分) 進行查詢,並且匹配的結果首先按照價格排序,然後按照相關性得分排序:
傳送請求:
POST /lxgzhw/_search
{
"query":{
"match_all":{}
},
"sort": [
{ "price": { "order": "desc" }},
{ "_score": { "order": "desc" }}
]
}
響應結果:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 6,
"max_score" : null,
"hits" : [
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "AF0-iHYBYIdsgnOgtk6r",
"_score" : 1.0,
"_source" : {
"title" : "apple手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 5899.0
},
"sort" : [
5899.0,
1.0
]
},
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_10-iHYBYIdsgnOgtk2r",
"_score" : 1.0,
"_source" : {
"title" : "華為手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 5288,
"subtitle" : "小米"
},
"sort" : [
5288.0,
1.0
]
},
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_l0-iHYBYIdsgnOgtk2r",
"_score" : 1.0,
"_source" : {
"title" : "小米電視4A",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 4288
},
"sort" : [
4288.0,
1.0
]
},
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"title" : "超米手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 3899.0
},
"sort" : [
3899.0,
1.0
]
},
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_F0-iHYBYIdsgnOgtk2r",
"_score" : 1.0,
"_source" : {
"title" : "大米手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 3288
},
"sort" : [
3288.0,
1.0
]
},
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_V0-iHYBYIdsgnOgtk2r",
"_score" : 1.0,
"_source" : {
"title" : "小米手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 2699
},
"sort" : [
2699.0,
1.0
]
}
]
}
}
23.高亮查詢(Highlighter)
什麼是高亮顯示
- 在進行關鍵字搜尋時,搜尋出的內容中的關鍵字會顯示不同的顏色,稱之為高亮
- 百度搜索關鍵字"理想國真恵玩"
高亮查詢請求
- ElasticSearch可以對查詢內容中的關鍵字部分,進行標籤和樣式(高亮)的設定。
- 在使用match查詢的同時,加上一個highlight屬性:
- pre_tags:前置標籤
- post_tags:後置標籤
- fields:需要高亮的欄位
- title:這裡宣告title欄位需要高亮,後面可以為這個欄位設定特有配置,也可以空
傳送請求:
POST /lxgzhw/_search
{
"query": {
"match": {
"title": "電視"
}
},
"highlight": {
"pre_tags": "<font color='pink'>",
"post_tags": "</font>",
"fields": {
"title": {}
}
}
}
響應結果:
{
"took" : 55,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.6548752,
"hits" : [
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_l0-iHYBYIdsgnOgtk2r",
"_score" : 0.6548752,
"_source" : {
"title" : "小米電視4A",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 4288
},
"highlight" : {
"title" : [
"小米<font color='pink'>電視</font>4A"
]
}
}
]
}
}
24.分頁查詢
傳送請求:
POST /lxgzhw/_search
{
"query": {
"match_all": {}
},
"size": 2,
"from": 0
}
- size:每頁顯示多少條
- from:當前頁的起始索引,int from = (當前頁 - 1) * 每頁條數
響應結果:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 6,
"max_score" : 1.0,
"hits" : [
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "AF0-iHYBYIdsgnOgtk6r",
"_score" : 1.0,
"_source" : {
"title" : "apple手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 5899.0
}
},
{
"_index" : "lxgzhw",
"_type" : "goods",
"_id" : "_10-iHYBYIdsgnOgtk2r",
"_score" : 1.0,
"_source" : {
"title" : "華為手機",
"images" : "http://image.leyou.com/12479122.jpg",
"price" : 5288,
"subtitle" : "小米"
}
}
]
}
}
結語
- 謝謝大家的閱讀,創業不易,如果您感覺對您有幫助,請打賞我一點
- 我微信18010070052,歡迎加我交流
- QQ交流群:630377015
- 零基礎想要學python或者Java全棧的同學歡迎報名跟我學習
- 有基礎想要學微服務或者RESTFul API,前後端分離開發,小程式的同學也可以找我報名學習哦