1. 程式人生 > 其它 >理想國Elasticsearch入門教程

理想國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:物件
  • 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)…等
  • 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(代表查詢所有)matchtermrange 等等
  • 查詢條件:查詢條件會根據型別的不同,寫法也有差異

響應結果

{
  "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_matchmatch類似,不同的是它可以在多個欄位中查詢。

傳送請求

本例中,我們在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,前後端分離開發,小程式的同學也可以找我報名學習哦