ElasticSearch 7.8.1 從入門到精通

陳彥斌發表於2020-08-10

學前導讀

  1. ElasticSearch對電腦配置要求較高記憶體至少4G以上,空閒2G記憶體,執行緒數4018+
  2. 學習的時候,推薦將ElasticSearch安裝到Linux或者mac上,極度不推薦裝Windows上(坑太多,伺服器部署的時候,也不會部署到Window上,學習用Windows上玩,不是耽誤自個時間麼)。如果是Window使用者想學這個,電腦自身至少16G,然後裝虛擬機器,在虛擬機器上搞個Linux玩
  3. Linux系統不建議裝6/6.5版本的(啟動的時候,會檢查核心是否3.5+,當然可以忽略這個檢查),推薦裝7+
  4. 自身電腦配置不高的話,怎麼辦呢?土豪做法,去買個雲伺服器叭,在雲伺服器上玩

注意事項

  上面第1、2點未滿足,又捨不得去買雲伺服器的小夥伴,就不要往下面看了,看了也白看,ElasticSearch對電腦配置要求較高,前置條件未滿足的話,服務是起不來的。

演示環境說明

  我演示的時候,是用的mac系統,上面裝了個虛擬機器,虛擬機器版本Centos6.5,jdk用的13,ElasticSearch用的版本是 7.8.1。這些我使用的包我下面也會提供,為了學習的話,儘量和我使用的版本一致,這樣大家碰到的問題都一樣,安裝過程中,我也猜了不少坑,都總結出來了,仔細閱讀文件就可以搗鼓出來。

什麼是搜尋引擎?

  常用的搜尋網站:百度、谷歌

資料的分類

結構化資料

  指具有固定格式或有限長度的資料,如資料庫,後設資料等。對於結構化資料,我們一般都是可以通過關係型資料庫(mysql、oracle)的table的方法儲存和搜尋,也可以建立索引。通過b-tree等資料結構快速搜尋資料

非結構化資料

  全文資料,指不定長或無固定格式的資料,如郵件,word等。對於非結構化資料,也即對全文資料的搜尋主要有兩種方式:順序掃描法,全文搜尋法

順序掃描法

  我們可以瞭解它的大概搜尋方式,就是按照順序掃描的方式查詢特定的關鍵字。比如讓你在一篇籃球新聞中,找出“科比”這個名字在那些段落出現過。那你肯定需要從頭到尾把文章閱讀一遍,然後標出關鍵字在哪些地方出現過

  這種方式毋庸置疑是最低效的,如果文章很長,有幾萬字,等你閱讀完這篇新聞找到“科比”這個關鍵字,那得花多少時間

全文搜尋

  對非結構化資料進行順序掃描很慢,我們是否可以進行優化?把非結構化資料想辦法弄得有一定結構不就好了嘛?將非結構化資料中的一部分資訊提取出來,重新組織,使其變得有一定結構,然後對這些有一定結構的資料進行搜尋,從而達到搜尋相對較快的目的。這種方式就構成了全文搜尋的基本思路。這部分從非結構化資料提取出的然後重新組織的資訊,就是索引。

什麼是全文搜尋引擎

  根據百度百科中的定義,全文搜尋引擎是目前廣泛應用的主流搜尋引擎。它的工作原理是計算機索引程式通過掃描文章中的每個詞,對每個詞建立一個索引,指明該詞在文章中出現的次數和位置,當使用者查詢時,檢索程式就根據事先建立的索引進行查詢,並將查詢的結果反饋給使用者。

常見的搜尋引擎

Lucene

  • Lucene是一個Java全文搜尋引擎,完全用Java編寫。lucene不是一個完整的應用程式,而是一個程式碼庫和API,可以很容易地用於嚮應用程式新增搜尋功能
  • 通過簡單的API提供強大的功能
    • 可擴充套件的高效能索引
    • 強大,準確,高效的搜尋演算法
    • 跨平臺解決方案
  • Apache軟體基金會
    • 在Apache軟體基金會提供的開源軟體專案的Apache社群的支援
    • 但是Lucene只是一個框架,要充分利用它的功能,需要使用Java,並且在程式中整合Lucene。需要很多的學習瞭解,才能明白它是如何執行的,熟練運用Lucene確實非常複雜

Solr

  • Solr是一個基於Lucene的Java庫構建的開源搜尋平臺。它以友好的方式提供Apache Lucene的搜尋功能。它是一個成熟的產品,擁有強大而廣泛的使用者社群。它能提供分散式索引,複製,負載均衡以及自動故障轉移和恢復。如果它被正確部署然後管理的好,他就能夠成為一個高可用,可擴充套件且容錯的搜尋引擎
  • 強大功能
    • 全文搜尋
    • 突出
    • 分面搜尋
    • 實時索引
    • 動態叢集
    • 資料庫整合
    • NoSQL功能和豐富的文件處理

ElasticSearch

  • ElasticSearch是一個開源,是一個機遇Apache Lucene庫構建的Restful搜尋引擎
  • ElasticSearch是Solr之後幾年推出的。它提供了一個分散式,多租戶能力的全文搜尋引擎,具有HTTP Web頁面和無架構JSON文件。ElasticSearch的官方客戶端提供Java、Php、Ruby、Perl、Python、.Net和JavaScript
  • 主要功能
    • 分散式搜尋
    • 資料分析
    • 分組和聚合
  • 應用場景
    • 維基百科
    • Stack Overflow
    • GitHub
    • 電商網站
    • 日誌資料分析
    • 商品價格監控網站
    • BI系統
    • 站內搜尋
    • 籃球論壇

搜尋引擎的快速搭建

環境準備

  注意,我使用的linux搭建的,當然Window(極度不推薦,坑太多)也能搭建,ElasticSearch安裝前需要先安裝jdk,這裡我使用的是jdk13,因為linux自帶jdk版本,需要先將之前的jdk版本解除安裝(點我直達),在安裝指定的jdk版本!!!

  開發環境,建議關閉防火牆,避免不必要的麻煩!!!!生產環境,視情況開啟埠號!!!!

service iptables stop   命令關閉防火牆,但是系統重啟後會開啟

chkconfig iptables off--關閉防火牆開機自啟動

「注意事項」

  ElasticSearch強依賴jdk環境的,所以一定要安裝對應的jdk版本並配置好相關的環境變數,比如ES7.X版本要裝jdk8以上的版本,而且是要官方來源的jdk。啟動的時候有可能會提示要裝jdk11,因為ES7以上官方都是建議使用jdk11,但是一般只是提示資訊,不影響啟動。

ES官網推薦JDK版本相容地址:點我直達

  ES強依賴JVM,也很吃記憶體,所以一定要保證你的機器至少空閒出2G以上記憶體。推薦使用Linux,可以本地搭建虛擬機器。

  啟動一定要使用非root賬戶!!!!這是ES強制規定的。ElasticSearch為了安全考慮,不讓使用root啟動,解決辦法是新建一個使用者,用此使用者進行相關的操作。如果你用root啟動,會報錯。如果是使用root賬戶安裝ES,首先給安裝包授權,比如chown -R 777 安裝包路徑。然後再使用非root賬戶啟動,具體的許可權配置,根據自己想要的配置。

補充

  高版本ElasticSearch自帶jdk版本的,Linux中我安裝的是jdk13,沒用ElasticSearch自帶的jdk,有興趣的小夥伴可以去研究下。

下載

官網地址:點我直達

我使用的包(推薦和我版本保持一致)

連結: https://pan.baidu.com/s/1jjNEErHtBu93HmvxKCT5Sw  密碼: kbcs

修改配置檔案

1、修改elasticsearch-x.x.x/config/elasticsearch.yml,主要修改成以下內容

cluster.name: my-application
node.name: node-1
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["127.0.0.1", "[::1]"]
cluster.initial_master_nodes: ["node-1"]

bootstrap.system_call_filter: false
http.cors.allow-origin: "*"
http.cors.enabled: true
http.cors.allow-headers : X-Requested-With,X-Auth-Token,Content-Type,Content-Length,Authorization
http.cors.allow-credentials: true

2、來到elasticsearch-x.x.x/bin下,執行:sh elasticsearch啟動,報錯,修改配置檔案elasticsearch-env

3、設定使用者和組 

groupadd elsearch
#新增使用者組,語法:groupadd 組名
useradd elsearch -g elsearch -p elasticsearch
#新增使用者,並將使用者新增到組中,語法:useradd 使用者名稱 -p 密碼 -g 組名
chown -R elsearch:elsearch  elasticsearch-6.3.0
# 給使用者組授權,語法:chown -R 使用者:組名 es安裝完整路徑

注意=================以上root使用者操作=============== 

注意=================以下es使用者操作================

注意:若es使用者密碼登入不上,在回到root使用者下,修改es使用者的密碼,語法:passwd 要修改使用者名稱

4、登入到es使用者下,繼續啟動ElasticSearch,執行:sh elasticsearch

報錯如下:
java.lang.UnsupportedOperationException: seccomp unavailable: requires kernel 3.5+ with CONFIG_SECCOMP and CONFIG_SECCOMP_FILTER compiled in

原因:我用的Centos6.5,其linux核心版本為2.6。而Elasticsearch的外掛要求至少3.5以上版本。


解決方案:禁用這個外掛即可
修改elasticsearch.yml檔案,在最下面新增如下配置:
bootstrap.system_call_filter: false

5.繼續啟動ElasticSearch,執行:sh elasticsearch

修改一下內容需要使用root許可權

報錯如下4條:
[1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65535]
[2]: max number of threads [1024] for user [es] is too low, increase to at least [4096]
[3]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
[4]: the default discovery settings are unsuitable for production use; at least one of [discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodes] must be configured

==========分割線===============
解決辦法如下
1、vim /etc/security/limits.conf檔案,新增
* soft nofile 65535
* hard nofile 65535

2、vim /etc/security/limits.conf檔案,新增
* soft nproc  4096
* hard nproc  4096

3、vim /etc/sysctl.conf 檔案,新增
vm.max_map_count=262144  

4、vim /var/soft/es7.8.1/elasticsearch-7.8.1/config/elasticsearch.yml 檔案,新增
cluster.initial_master_nodes: ["node-1"]

修改完之後,一定要重啟,重啟,重啟,重要的事兒說三遍!!!!!

上面第2條問題,執行緒數修改不了,可以嘗試使用這個方法修改執行緒數

Elasticsearch7.8.1 [1]: max number of threads [1024] for user [es] is too low, increase to at least [4096]異常

根據linux系統差異,有時候需要來點終極解決方案

新建: /etc/security/limits.d/test-limits.conf

cat>>test-limits.conf



然後加下內容:

* soft nofile 65535

* hard nofile 65535

* soft nproc 4096

* hard nproc 4096


ctrl+d儲存即可;


然後重啟伺服器即可;

配置小結

  1、第一次配置過程中,踩了不少坑,我踩過的坑,都在上面記錄了

  2、如果照我上面哪個方法還解決不了,自行根據ElasticSearch日誌,百度去找答案叭····

啟動

正常啟動

進入軟體的安裝目錄,進入到bin
執行:sh elasticsearch

守護進行啟動

進入軟體的安裝目錄,進入到bin
執行:sh elasticsearch -d -p pid

驗證

  開啟瀏覽器輸入:127.0.0.1:9200

ElasticSearch目錄結構介紹

型別 描述 預設位置 設定
bin
⼆進位制指令碼包含啟動節點的elasticsearch
{path.home}/bin
 
conf
配置⽂件包含elasticsearch.yml 
{path.home}/confifig
path.conf
data
在節點上申請的每個index/shard的資料⽂件的位置。
可容納多個位置
{path.home}/data
path.data
logs
⽇志⽂件位置
{path.home}/logs
path.logs
plugins
外掛⽂件位置。每個外掛將包含在⼀個⼦⽬錄中。
{path.home}/plugins
path.plugins

ElasticSearch快速入門

核心概念

前言

  傳統資料庫查詢資料的操作步驟是這樣的:建立資料庫->建表->插入資料->查詢

索引(index)

  一個索引可以理解成一個關係型資料庫

型別(type)

  一個type就像一類表,比如user表、order表

  注意

    1、ES 5.X中一個index可以有多種type

    2、ES 6.X中一個index只能有一種type

    3、ES 7.X以後已經移除type這個概念

對映(mapping)

  mapping定義了每個欄位的型別等資訊。相當於關係型資料庫中的表結構

文件(document)

  一個document相當於關係型資料庫中的一行記錄

欄位(field)

  相當於關係型資料庫表的欄位

叢集(cluster)

  叢集由一個或多個節點組成,一個叢集由一個預設名稱“elasticsearch”

節點(node)

  叢集的節點,一臺機器或者一個程式

分片和副本(shard)

  • 副本是分片的副本。分片有主分片(primary Shard)和副本分片(replica Shard)之分
  • 一個Index資料在屋裡上被分佈在多個主分片中,每個主分片只存放部分資料
  • 每個主分片可以有多個副本,叫副本分片,是主分片的複製

RESTful風格的介紹

介紹

  •  RESTful是一種架構的規範與約束、原則,符合這種規範的架構就是RESTful架構
  • 先看REST是什麼意思,英文Representational state transfer表述性狀態轉移,其實就是對資源的標書性狀態轉移,即通過HTTP動詞來實現資源的狀態扭轉
  • 資源是REST系統的核心概念。所有的設計都是以資源為中心
  • elasticsearch使用RESTful風格api來設計的

方法

action 描述
HEAD 只獲取某個資源的頭部資訊
GET 獲取資源
POST 建立或更新資源
PUT 建立或更新資源
DELETE 刪除資源
GET /user:列出所有的⽤戶
POST /user:新建⼀個⽤戶
PUT /user:更新某個指定⽤戶的資訊
DELETE /user/ID:刪除指定⽤戶

除錯工具

Postman工具(推薦)

curl工具

獲取elasticcsearch狀態

curl -X GET "http://localhost:9200"

新建一個文件

curl -X PUT "localhost:9200/xdclass/_doc/1" -H 'Content-Type:
application/json' -d' {
"user" : "louis",
"message" : "louis is good"
}

刪除一個文件

curl -X DELETE "localhost:9200/xdclass/_doc/1"

索引的使用

新增

單個獲取

批量獲取

刪除

獲取所有

方式一

方式二

判斷索引是否存在(存在,返回200,不存在404)

關閉索引

  此時再次查詢cba時,返回json會多一行

開啟索引

  關閉索引標記消失

對映的使用

介紹

  定義索引的結構,之前定義一個nba索引,但是沒有定義他的結構,我們現在開始建立mapping;

  type="keyword":是一個關鍵字,不會被分詞

  type="text":會被分詞,使用的是全文索引

新增

json格式

{
    "properties": {
        "name": {
            "type": "text"
        },
        "team_name": {
            "type": "text"
        },
        "position": {
            "type": "keyword"
        },
        "play_year": {
            "type": "keyword"
        },
        "jerse_no": {
            "type": "keyword"
        }
    }
}

獲取

批量獲取

獲取所有mapping

方式一

方式二

新增一次欄位

文件的操作

新增

不指定索引方式新增

踩坑(要POST請求)

PUT請求改POST

自動建立索引

  • 檢視auto_create_index開關狀態,請求:http://ip:port/_cluster/settings

  • 當索引不存在並且auto_create_index為true的時候,新增文件時會自動建立索引
  • 修改auto_create_index狀態
    • put方式:ip:port/_cluster/settings

{
"persistent": {
    "action.auto_create_index": "false"
 }
}

  當auto_create_index=false時,指定一個不存在的索引,新增文件

{
    "name":"楊超越",
    "team_name":"夢之隊",
    "position":"組織後衛",
    "play_year":"0",
    "jerse_no":"18"
}

指定操作型別

PUT請求:ip:port/xxx/_doc/1?op_type=create

文件檢視

檢視多個文件

方式一

{
    "docs": [{
            "_index": "nba",
            "_type": "_doc",
            "_id": "1"
        },
        {
            "_index": "nba",
            "_type": "_doc",
            "_id": "2"
        }
    ]
}

方式二

方式三

方式四

修改

向_source欄位,增加一個欄位

{
    "script": "ctx._source.age = 18"
}

從source欄位,刪除一個欄位

{
    "script": "ctx._source.remove(\"age\")"
}

根據引數值,更新指定文件的欄位

  upsert當指定的文件不存在時,upsert引數包含的內容將會被插入到索引中,作為一個新文件;如果指定的文件存在,ElasticSearch引擎將會執行指定的更新邏輯。

刪除文件

搜尋的簡單使用

準備工作

刪除nba索引

新建一個索引

並指定mapping

{
    "mappings": {
        "properties": {
            "name": {
                "type": "text"
            },
            "team_name": {
                "type": "text"
            },
            "position": {
                "type": "text"
            },
            "play_year": {
                "type": "long"
            },
            "jerse_no": {
                "type": "keyword"
            }
        }
    }
}

新增document

192.168.199.170:9200/nba/_doc/1
{
    "name": "哈登",
    "team_name": "⽕箭",
    "position": "得分後衛",
    "play_year": 10,
    "jerse_no": "13"
}
192.168.199.170:9200/nba/_doc/2
{
    "name": "庫⾥",
    "team_name": "勇⼠",
    "position": "控球后衛",
    "play_year": 10,
    "jerse_no": "30"
}
192.168.199.170:9200/nba/_doc/3
{
    "name": "詹姆斯",
    "team_name": "湖⼈",
    "position": "⼩前鋒",
    "play_year": 15,
    "jerse_no": "23"
}

詞條查詢(term)

  詞條查詢不會分析查詢條件,只有當詞條和查詢字串完全匹配時,才匹配搜尋。

單挑term查詢

{
    "query": {
        "term": {
            "jerse_no": "23"
        }
    }
}

多條term查詢

{
    "query": {
        "terms": {
            "jerse_no": [
                "23",
                "13"
            ]
        }
    }
}

全文查詢(full text)

  ElasticSearch引擎會先分析查詢字串,將其拆分成多個分詞,只要已分析的欄位中包含詞條的任意一個,或全部包含,就匹配查詢條件,返回該文件;如果不包含任意一個分詞,表示沒有任何問的那個匹配查詢條件

match_all

{
    "query": {
        "match_all": {}
    },
    "from": 0,
    "size": 10
}

match

{
    "query": {
        "match": {
            "position":"後衛"
        }
    },
    "from": 0,
    "size": 10
}

multi_match

{
    "query": {
        "multi_match": {
            "query": "shooter",
            "fields": ["title", "name"]
        }
    }
}
post 192.168.199.170:9200/nba/_update/2
{
    "doc": {
        "name": "庫⾥",
        "team_name": "勇⼠",
        "position": "控球后衛",
        "play_year": 10,
        "jerse_no": "30",
        "title": "the best shooter"
    }
}

match_phrase

  類似於詞條查詢,精準查詢

match_phrase_prefix

  字首匹配

{
    "query": {
        "match_phrase_prefix": {
            "title": "the best s"
        }
    }
}
post 192.168.199.170:9200/nba/_update/3
{
    "doc": {
        "name": "詹姆斯",
        "team_name": "湖⼈",
        "position": "⼩前鋒",
        "play_year": 15,
        "jerse_no": "23",
        "title": "the best small forward"
    }
}

分詞器的介紹和使用

什麼是分詞器

  • 將使用者輸入的一段文字,按照一定邏輯,分析成多個詞語的一種工具
  • example:The best 3-points shooter is Curry!

常用的內建分詞器

  1. standard analyzer
  2. simple analyzer
  3. whitespace analyzer
  4. stop analyzer
  5. language analyzer
  6. pattern analyzer

standard analyzer

  標準分析器是預設分詞器,如果未指定,則使用該分詞器

{
    "analyzer": "standard",
    "text": "The best 3-points shooter is Curry!"
}

simple analyzer

  simple分析器當他遇到只要不是字母的字元,就將文字解析成term,而且所有的term都是小寫

whitespace analyzer

  whitespace分析器,當他遇到空白字元時,就將文字解析成terms

stop analyzer

  stop分析器和simple分析器很想,唯一不同的是,stop分析器增加了對刪除停止詞的支援,預設使用了english停止詞

  stopwords預定義的停止詞列表,比如(ths,a,an,this,of,at)等等

language analyzer

(特定的語⾔的分詞器,⽐如說,english,英語分詞器),內建語⾔:arabic, armenian,
basque, bengali, brazilian, bulgarian, catalan, cjk, czech, danish, dutch, english, fifinnish,
french, galician, german, greek, hindi, hungarian, indonesian, irish, italian, latvian,
lithuanian, norwegian, persian, portuguese, romanian, russian, sorani, spanish,
swedish, turkish, thai 

pattern analyzer

  用正規表示式將文字分割成sterms,預設的正規表示式是\W+

選擇分詞器

put 192.168.199.170:9200/my_index
{
    "settings": {
        "analysis": {
            "analyzer": {
                "my_analyzer": {
                    "type": "whitespace"
                }
            }
        }
    },
    "mappings": {
        "properties": {
            "name": {
                "type": "text"
            },
            "team_name": {
                "type": "text"
            },
            "position": {
                "type": "text"
            },
            "play_year": {
                "type": "long"
            },
            "jerse_no": {
                "type": "keyword"
            },
            "title": {
                "type": "text",
                "analyzer": "my_analyzer"
            }
        }
    }
}

{
    "name": "庫⾥",
    "team_name": "勇⼠",
    "position": "控球后衛",
    "play_year": 10,
    "jerse_no": "30",
    "title": "The best 3-points shooter is Curry!"
}

{
    "query": {
        "match": {
            "title": "Curry!"
        }
    }
}

常見中文分詞器

預設的分詞standard

{
    "analyzer": "standard",
    "text": "⽕箭明年總冠軍" 
}

常見分詞器

  • smartCN一個簡單的中文或中英文混合文字的分詞器
  • IK分詞器,更智慧更友好的中文分詞器

安裝smartCN

  • sh elasticsearch-plugin install analysis-smartcn

校驗

  安裝後重啟

{
    "analyzer": "smartcn",
    "text": "⽕箭明年總冠軍" 
}

解除安裝

  sh elasticsearch-plugin remove analysis-smartcn

IK分詞器

  下載地址:點我直達

安裝,解壓到plugins目錄 

然後重啟 

常見的欄位型別

資料型別

  • 核心資料型別
  • 複雜資料型別
  • 專用資料型別

核心資料型別

字串

  • text:用於全文索引,該型別的欄位將通過分詞器進行分詞
  • keyword:不分詞,只能搜尋該欄位的完整的值

數值型

  • long、integer、short、byte、double、float、half_float、scaled_float

布林

  • boolean

二進位制

  • binary:該型別的欄位把值當做經過base64編碼的字串,預設不儲存,且不可搜尋

範圍型別

  1. 範圍型別表示值是一個範圍,而不是一個具體的值
  2. integer_range、float_range、long_range、double_range、date_range
  3. 比如age型別是integer_range,那麼值可以是{"gte":20,"lte":40};搜尋"term":{"age":21}可以搜尋該值

日期-date

  由於json型別沒有date型別,所以es通過識別字串是否符合format定義的格式來判斷是否為date型別

  format預設為:strict_date_optional_time || epoch_millis

  格式

    "2022-01-01" "2022/01/01 12:10:30" 這種字串格式

  從開始紀元(1970年1月1日0點)開始的毫秒數

PUT 192.168.199.170:9200/nba/_mapping

{
    "properties": {
        "name": {
            "type": "text"
        },
        "team_name": {
            "type": "text"
        },
        "position": {
            "type": "text"
        },
        "play_year": {
            "type": "long"
        },
        "jerse_no": {
            "type": "keyword"
        },
        "title": {
            "type": "text"
        },
        "date": {
            "type": "date"
        }
    }
}
POST 192.168.199.170:9200/nba/_doc/4

{
    "name": "蔡x坤",
    "team_name": "勇⼠",
    "position": "得分後衛",
    "play_year": 10,
    "jerse_no": "31",
    "title": "打球最帥的明星",
    "date": "2020-01-01"
}
POST 192.168.199.170:9200/nba/_doc/5

{
    "name": "楊超越",
    "team_name": "猴急",
    "position": "得分後衛",
    "play_year": 10,
    "jerse_no": "32",
    "title": "打球最可愛的明星",
    "date": 1610350870
}
POST 192.168.199.170:9200/nba/_doc/6

{
    "name": "吳亦凡",
    "team_name": "湖⼈",
    "position": "得分後衛",
    "play_year": 10,
    "jerse_no": "33",
    "title": "最會說唱的明星",
    "date": 1641886870000
}

複雜資料型別

資料型別 Array

  • ES中沒有專門的資料型別,直接使用[]定義介面,陣列中所有的值必須是同一種資料型別,不支援混合資料型別的陣列
  • 字串陣列["one","two"]
  • 整數陣列[1,2]
  • Object物件陣列[{"name":"alex","age":18},{"name":"tom","age":18}]

物件型別Object

POST 192.168.199.170:9200/nba/_doc/8

{
    "name": "吳亦凡",
    "team_name": "湖⼈",
    "position": "得分後衛",
    "play_year": 10,
    "jerse_no": "33",
    "title": "最會說唱的明星",
    "date": "1641886870",
    "array": [
        "one",
        "two"
    ],
    "address": {
        "region": "China",
        "location": {
            "province": "GuangDong",
            "city": "GuangZhou"
        }
    }
}

索引方式

"address.region": "China",
"address.location.province": "GuangDong",
"address.location.city": "GuangZhou"
POST 192.168.199.170:9200/nba/_search

{
    "query": {
        "match": {
            "address.region": "china"
        }
    }
}

專用資料型別

IP型別

  IP型別的欄位用於儲存IPv4和IPv6的地址,本質上是一個長整形欄位

POST 192.168.199.170:9200/nba/_mapping

{
    "properties": {
        "name": {
            "type": "text"
        },
        "team_name": {
            "type": "text"
        },
        "position": {
            "type": "text"
        },
        "play_year": {
            "type": "long"
        },
        "jerse_no": {
            "type": "keyword"
        },
        "title": {
            "type": "text"
        },
        "date": {
            "type": "date"
        },
        "ip_addr": {
            "type": "ip"
        }
    }
}
PUT 192.168.199.170:9200/nba/_doc/9

{
    "name": "吳亦凡",
    "team_name": "湖⼈",
    "position": "得分後衛",
    "play_year": 10,
    "jerse_no": "33",
    "title": "最會說唱的明星",
    "ip_addr": "192.168.1.1"
}
POST 192.168.199.170:9200/nba/_search

{
    "query": {
        "term": {
            "ip_addr": "192.168.0.0/16"
        }
    }
}

kibana工具的安裝和使用

簡介

  視覺化工具kibana的安裝和使用

下載

點我直達

賦許可權

 chown -R es:es781g /var/soft/kibana-7.8.1-linux-x86_64
# 給使用者組授權,語法:chown -R 使用者:組名 es安裝完整路徑

kibana.yml

server.port: 5601   #kibana埠
server.host: "10.0.0.169"    #繫結的主機IP地址
elasticsearch.hosts: ["http://10.0.0.169:9200"]      #elasticsearch的主機IP
kibana.index: ".kibana"     #開啟此選項
i18n.locale: "zh-CN"     #kibana預設文字是英文,變更成中文

啟動

進⼊到⽂件夾的bin⽬錄,執⾏sh kibana

訪問

ip:5601

簡單使用

  後面示例,會大量使用該工具

ES之批量匯入資料

簡介

  手把手教你批量匯入資料

Bulk

  ES提供了一個叫bulk的API來進行批量操作

批量匯入

資料

{"index": {"_index": "book", "_type": "_doc", "_id": 1}}
{"name": "權⼒的遊戲"} {"index": {"_index": "book", "_type": "_doc", "_id": 2}}
{"name": "瘋狂的⽯頭"}

POST bulk

curl -X POST "192.168.199.170:9200/_bulk" -H 'Content-Type: application/json' --data-binary @test

 

 

ES之term的多種查詢

介紹

  • 單詞級別查詢
  • 這些查詢通常用於結構化的資料,比如:number,data,keyword等,而不是對text
  • 也就是說,全文查詢之前要先對文字內容進行分詞,而單詞級別的查詢直接在相應欄位的反向索引中精確查詢,單詞級別的查詢一般用於數值、日期等型別的欄位上

準備工作

  1. 刪除nba
  2. 新增nba索引
{"mappings":{"properties":{"birthDay":{"type":"date"},"birthDayStr": {"type":"keyword"},"age":{"type":"integer"},"code": {"type":"text"},"country":{"type":"text"},"countryEn": {"type":"text"},"displayAffiliation":{"type":"text"},"displayName": {"type":"text"},"displayNameEn":{"type":"text"},"draft": {"type":"long"},"heightValue":{"type":"float"},"jerseyNo": {"type":"text"},"playYear":{"type":"long"},"playerId": {"type":"keyword"},"position":{"type":"text"},"schoolType": {"type":"text"},"teamCity":{"type":"text"},"teamCityEn": {"type":"text"},"teamConference": {"type":"keyword"},"teamConferenceEn":{"type":"keyword"},"teamName": {"type":"keyword"},"teamNameEn":{"type":"keyword"},"weight": {"type":"text"}}}}

  • 批量匯入player

Term query精準匹配查詢

POST nba/_search
{
  "query": {
    "term": {
      "jerseyNo": "23"
    }
  },
  "from": 0,
  "size": 20
}

Exsit Query在特定的欄位中查詢非空值的文件(查詢隊名非空的球員)

Prefix Query查詢包含帶有指定字首term的文件(查詢隊名為Rock開頭的球員)

Wildcard Query支援萬用字元查詢,*表示任意字元,?表示任意單個字元(查詢火箭隊的球員)

Regexp Query正規表示式查詢(查詢火箭隊的球員)

Ids Query(查詢id為1和2的球員)

ES的範圍查詢

查詢指定欄位在指定範圍內包含值(日期、數字或字串)的文件

  查詢在nba打球在2年到10年以內的球員

 

POST nba/_search
{
  "query": {
    "range": {
      "playYear": {
        "gte": 2,
        "lte": 10
      }
    }
  },
  "from": 0,
  "size": 20
}

查詢1999年到2020年出生的球員

 

POST nba/_search
{
  "query": {
    "range": {
      "birthDay": {
        "gte": "01/01/1999",
        "lte": "2020",
        "format": "dd/MM/yyyy||yyyy"
      }
    }
  },
  "from": 0,
  "size": 20
}

ES的布林查詢

布林查詢

type description
must 必須出現在匹配文件中
filter 必須出現在文件中,但是不打分
must_not 不能出現在文件中
should 應該出現在文件中

must(查詢名字叫做james的球員)

 

POST nba/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "displayNameEn": "james"
          }
        }
      ]
    }
  },
  "from": 0,
  "size": 20
}

效果通must,但是不打分(查詢名字叫做james的球員)

 

POST nba/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "match": {
            "displayNameEn": "james"
          }
        }
      ]
    }
  },
  "from": 0,
  "size": 20
}

must_not(查詢名字叫做James的西部球員)

 

POST nba/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "displayNameEn": "james"
          }
        }
      ],
      "must_not": [
        {
          "term": {
            "teamConferenceEn": {
              "value": "Eastern"
            }
          }
        }
      ]
    }
  },
  "from": 0,
  "size": 20
}

組合起來含義:一定不在東部的james

should(查詢名字叫做James的打球時間應該在11到20年西部球員)

即使匹配不到也返回,只是評分不同

 

POST nba/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "displayNameEn": "james"
          }
        }
      ],
      "must_not": [
        {
          "term": {
            "teamConferenceEn": {
              "value": "Eastern"
            }
          }
        }
      ],
      "should": [
        {
          "range": {
            "playYear": {
              "gte": 11,
              "lte": 20
            }
          }
        }
      ]
    }
  },
  "from": 0,
  "size": 20
}

如果minimum_should_match=1,則變成要查出名字叫做James的打球時間在11年到20年西部球員

 

POST nba/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "displayNameEn": "james"
          }
        }
      ],
      "must_not": [
        {
          "term": {
            "teamConferenceEn": {
              "value": "Eastern"
            }
          }
        }
      ],
      "should": [
        {
          "range": {
            "playYear": {
              "gte": 11,
              "lte": 20
            }
          }
        }
      ],
      "minimum_should_match": 1
    }
  },
  "from": 0,
  "size": 20
}

minimum_should_match代表了最小匹配經度,如果設定minimum_should_match=1,那麼should語句中至少需要有一個條件滿足

ES的排序

火箭隊中按打球時間從大到小排序的球員

 

POST nba/_search
{
  "query": {
    "match": {
      "teamNameEn": "Rockets"
    }
  },
  "sort": [
    {
      "playYear": {
        "order": "desc"
      }
    }
  ], 
  "from": 0,
  "size": 20
}

火箭隊中按打球時間從大到小,如果年齡相同則按照身高從高到低排序的球員

 

POST nba/_search
{
  "query": {
    "match": {
      "teamNameEn": "Rockets"
    }
  },
  "sort": [
    {
      "playYear": {
        "order": "desc"
      }
    },{
      "heightValue": {
        "order": "asc"
      }
    }
  ],
  "from": 0,
  "size": 20
}

ES聚合查詢之指標聚合

ES聚合查詢是什麼

  1. 聚合查詢是資料庫重要功能特性,完成對一個查詢得到的資料集的聚合計算,如:找出某欄位(或計算表示式的結果)的最大值,最小值,計算和,平均值等。ES作為搜尋引擎,同樣提供了強大的聚合分析能力
  2. 對一個資料集求最大、最小、和、平均值等指標的聚合,在ES中稱為指標聚合
  3. 而關係型資料庫中除了有聚合函式外,還可以對查詢出的資料進行分組group by,再在組上進行指標聚合。在ES中稱為“桶聚合

max min sum avg

求出火箭隊球員的平均年齡

POST /nba/_search
{
  "query": {
    "term": {
      "teamNameEn": {
        "value": "Rockets"
      }
    }
  },
  "aggs": {
    "avgAge": {
      "avg": {
        "field": "age"
      }
    }
  },
  "size": 0
}

value_count統計非空欄位的文件數

求出火箭隊中球員打球時間不為空的數量

 

POST /nba/_search
{
  "query": {
    "term": {
      "teamNameEn": {
        "value": "Rockets"
      }
    }
  },
  "aggs": {
    "countPlayerYear": {
      "value_count": {
        "field": "playYear"
      }
    }
  },
  "size": 0
}

查出火箭隊有多少名球員

 

POST /nba/_search
{
  "query": {
    "term": {
      "teamNameEn": {
        "value": "Rockets"
      }
    }
  }
}

Cardinality值去重計數

查出火箭隊中年齡不同的數量

 

POST /nba/_search
{
  "query": {
    "term": {
      "teamNameEn": {
        "value": "Rockets"
      }
    }
  },
  "aggs": {
    "countAget": {
      "cardinality": {
        "field": "age"
      }
    }
  },
  "size": 0
}

stats統計count max min avg sum5個值

查出火箭隊球員的年齡stats

 

POST /nba/_search
{
  "query": {
    "term": {
      "teamNameEn": {
        "value": "Rockets"
      }
    }
  },
  "aggs": {
    "statsAge": {
      "stats": {
        "field": "age"
      }
    }
  },
  "size": 0
}

Extended stats比stats多4個統計結果:平方和、方差、標準差、平均值加/減兩個標準差的區間

查詢火箭隊球員的年齡Extend stats

 

POST /nba/_search
{
  "query": {
    "term": {
      "teamNameEn": {
        "value": "Rockets"
      }
    }
  },
  "aggs": {
    "extendStatsAge": {
      "extended_stats": {
        "field": "age"
      }
    }
  },
  "size": 0
}

Percentiles佔比百分位對應的值統計,預設返回【1,5,25,50,75,95,99】分位上的值

查出火箭的球員的年齡佔比

 

POST /nba/_search
{
  "query": {
    "term": {
      "teamNameEn": {
        "value": "Rockets"
      }
    }
  },
  "aggs": {
    "pecentAge": {
      "percentiles": {
        "field": "age"
      }
    }
  },
  "size": 0
}

查出火箭的球員的年齡佔比(指定分位值)

 

POST /nba/_search
{
  "query": {
    "term": {
      "teamNameEn": {
        "value": "Rockets"
      }
    }
  },
  "aggs": {
    "pecentAge": {
      "percentiles": {
        "field": "age",
        "percents": [
          20,
          50,
          75
        ]
      }
    }
  },
  "size": 0
}

ES聚合查詢之桶聚合

ES聚合分析是什麼

  • 聚合分析是資料庫中重要的功能特性,完成對一個查詢的資料集中資料的聚合計算,如:找出欄位(或計算表示式的結果)的最大值、最小值、計算和、平均值等。ES作為搜尋引擎相容資料庫,同樣提供了強大的聚合分析能力
  • 對一個資料集求最大、最小、和、平均值等指標的聚合,在ES中稱為指標聚合
  • 而關係型資料庫中除了有聚合函式外,還可以對查詢出的資料進行分組group by,再在組上進行遊標聚合。在ES中稱為桶聚合

Terms Aggregation根據欄位項分組聚合

火箭隊根據年齡進行分組

 

POST /nba/_search
{
  "query": {
    "term": {
      "teamNameEn": {
        "value": "Rockets"
      }
    }
  },
  "aggs": {
    "aggsAge": {
      "terms": {
        "field": "age",
        "size": 10
      }
    }
  },
  "size": 0
}

Order分組聚合排序

火箭隊根據年齡進行分組,分組資訊通過年齡從大到小排序(通過指定欄位)

 

POST /nba/_search
{
  "query": {
    "term": {
      "teamNameEn": {
        "value": "Rockets"
      }
    }
  },
  "aggs": {
    "aggsAge": {
      "terms": {
        "field": "age",
        "size": 10,
        "order": {
          "_key": "desc"
        }
      }
    }
  },
  "size": 0
}

火箭隊根據年齡進行分組,分組資訊通過文件數從大到小排序(通過文件數)

 

POST /nba/_search
{
  "query": {
    "term": {
      "teamNameEn": {
        "value": "Rockets"
      }
    }
  },
  "aggs": {
    "aggsAge": {
      "terms": {
        "field": "age",
        "size": 10,
        "order": {
          "_count": "desc"
        }
      }
    }
  },
  "size": 0
}

每支球隊按該隊所有球員的平均年齡進行分組排序(通過分組指標值)

 

POST /nba/_search
{
  "query": {
    "term": {
      "teamNameEn": {
        "value": "Rockets"
      }
    }
  },
  "aggs": {
    "avgAge": {
      "avg": {
        "field": "age"
      }
    }
  },
  "size": 0
}

篩選分組聚合

湖人和火箭隊按球隊平均年齡進行分組排序(指定值列表)

 

POST /nba/_search
{
  "aggs": {
    "aggsTeamName": {
      "terms": {
        "field": "teamNameEn",
        "include": [
          "Lakers",
          "Rockets",
          "Warriors"
        ],
        "exclude": [
          "Warriors"
        ],
        "size": 30,
        "order": {
          "avgAge": "desc"
        }
      },
      "aggs": {
        "avgAge": {
          "avg": {
            "field": "age"
          }
        }
      }
    }
  },
  "size": 0
}

湖人和火箭隊按球隊平均年齡進行分組排序(正規表示式匹配值)

 

POST /nba/_search
{
  "aggs": {
    "aggsTeamName": {
      "terms": {
        "field": "teamNameEn",
        "include": "Lakers|Ro.*|Warriors.*",
        "exclude": "Warriors",
        "size": 30,
        "order": {
          "avgAge": "desc"
        }
      },
      "aggs": {
        "avgAge": {
          "avg": {
            "field": "age"
          }
        }
      }
    }
  },
  "size": 0
}

Range Aggregation範圍分組聚合

NBA球員年齡按20,20-35,35這樣分組

 

POST /nba/_search
{
  "aggs": {
    "ageRange": {
      "range": {
        "field": "age",
        "ranges": [
          {
            "to": 20
          },
          {
            "from": 20,
            "to": 35
          },
          {
            "to": 35
          }
        ]
      }
    }
  },
  "size": 0
}

NBA球員年齡按20,20-35,35這樣分組(起別名)

 

Date Range Aggregation時間範圍分組聚合

NBA球員按出生年月分組

 

POST /nba/_search
{
  "aggs": {
    "birthDayRange": {
      "date_range": {
        "field": "birthDay",
        "format": "MM-yyy",
        "ranges": [
          {
            "to": "01-1989"
          },
          {
            "from": "01-1989",
            "to": "01-1999"
          },
          {
            "from": "01-1999",
            "to": "01-2009"
          },
          {
            "from": "01-2009"
          }
        ]
      }
    }
  },
  "size": 0
}

Date Histogram Aggregation時間柱狀圖聚合

按天、月、年等進行聚合統計。可按year(1y),quarter(1q),month(1M),week(1w),day(1d),hour(1h),minute(1m),second(1s)間隔聚合

NBA球員按出生年分組

POST /nba/_search
{
  "aggs": {
    "birthday_aggs": {
      "date_histogram": {
        "field": "birthDay",
        "format": "yyyy",
        "interval": "year"
      }
    }
  },
  "size": 0
}

 

ES之query_string查詢

簡介

  query_string查詢,如果熟悉lucene的查詢語法,我們可以直接用lucene查詢語法寫一個查詢串進行查詢,ES中接到請求後,通過查詢解析器,解析查詢串生成對應的查詢。

指定單個欄位查詢

 

POST /nba/_search
{
  "query": {
    "query_string": {
      "default_field": "displayNameEn",
      "query": "james OR curry"
    }
  }, 
  "size": 100
}

 

POST /nba/_search
{
  "query": {
    "query_string": {
      "default_field": "displayNameEn",
      "query": "james AND harden"
    }
  }, 
  "size": 100
}

指定多個欄位查詢

 

ElasticSearch的高階使用

別名有什麼用

  在開發中,隨著業務需求的迭代,較老的業務邏輯就要面臨更新甚至是重構,而對於es來說,為了適應新的業務邏輯,可能就要對原有的索引做一些修改,比如對某欄位做調整,甚至是重構索引。而做這些操作的時候,可能會對業務造成影響,甚至是停機調整等問題。由此,es提供了索引別名來解決這些問題。索引別名就像一個快捷方式或軟連線,可以指向一個或多個索引,也可以給任意一個需要索引名的API來使用。別名的應用為程式提供了極大地靈活性。

查詢別名

GET /nba/_alias

GET /_alias

 

 

 

 

新增別名

 

 

POST /_aliases
{
  "actions": [
    {
      "add": {
        "index": "nba",
        "alias": "nba_v1.0"
      }
    }
  ]
}

 

刪除別名

 

方式一
POST /_aliases
{
  "actions": [
    {
      "remove": {
        "index": "nba",
        "alias": "nba_v1.0"
      }
    }
  ]
}

方式二
DELETE /nba/_alias/nba_v1.0

重新命名別名

 

POST /_aliases
{
  "actions": [
    {
      "remove": {
        "index": "nba",
        "alias": "nba_v1.0"
      }
    },
    {
      "add": {
        "index": "nba",
        "alias": "nba_v2.0"
      }
    }
  ]
}

為多個索引指定一個別名

 

POST /_aliases
{
  "actions": [
    {
      "add": {
        "index": "nba",
        "alias": "nba_v2.0"
      }
    },{
      "add": {
        "index": "cba",
        "alias": "cba_v2.0"
      }
    }
  ]
}

為同個索引指定多個別名

 

POST /_aliases
{
  "actions": [
    {
      "add": {
        "index": "nba",
        "alias": "nba_v2.0"
      }
    },{
      "add": {
        "index": "nba",
        "alias": "cba_v2.2"
      }
    }
  ]
}

通過別名讀索引

當別名指定了一個索引,則查出一個索引

 

當別名指定了多個索引,則查出多個索引

GET /nba_v2.2

通過別名寫索引

當別名指定了一個索引,則可以做寫的操作

 

POST /nba_v2.0/_doc/566
{
  "countryEn": "Croatia",
  "teamName": "快船",
  "birthDay": 858661200000,
  "country": "克羅埃西亞",
  "teamCityEn": "LA",
  "code": "ivica_zubac",
  "displayAffiliation": "Croatia",
  "displayName": "伊維察 祖巴茨哥哥",
  "schoolType": "",
  "teamConference": "⻄部",
  "teamConferenceEn": "Western",
  "weight": "108.9 公⽄",
  "teamCity": "洛杉磯",
  "playYear": 3,
  "jerseyNo": "40",
  "teamNameEn": "Clippers",
  "draft": 2016,
  "displayNameEn": "Ivica Zubac",
  "heightValue": 2.16,
  "birthDayStr": "1997-03-18",
  "position": "中鋒",
  "age": 22,
  "playerId": "1627826"
}

當別名指定了多個索引,可以指定寫某個索引

POST /_aliases
{
  "actions": [
    {
      "add": {
        "index": "nba",
        "alias": "national_player",
        "is_write_index": true
      }
    },
    {
      "add": {
        "index": "cba",
        "alias": "national_player"
      }
    }
  ]
}
POST /national_player/_doc/566
{
  "countryEn": "Croatia",
  "teamName": "快船",
  "birthDay": 858661200000,
  "country": "克羅埃西亞",
  "teamCityEn": "LA",
  "code": "ivica_zubac",
  "displayAffiliation": "Croatia",
  "displayName": "伊維察 祖巴茨妹妹",
  "schoolType": "",
  "teamConference": "⻄部",
  "teamConferenceEn": "Western",
  "weight": "108.9 公⽄",
  "teamCity": "洛杉磯",
  "playYear": 3,
  "jerseyNo": "40",
  "teamNameEn": "Clippers",
  "draft": 2016,
  "displayNameEn": "Ivica Zubac",
  "heightValue": 2.16,
  "birthDayStr": "1997-03-18",
  "position": "中鋒",
  "age": 22,
  "playerId": "1627826"
}

ES之重建索引

簡介

  ElasticSearch是一個實時的分散式搜尋引擎,為使用者提供搜尋服務,當我們決定儲存某種資料時,在建立索引的時候需要將資料結構完整確定下來,於此同時索引的設定和很多固定配置將不能修改。當需要改變資料結構時,就需要重新建立索引,為此,Elastic團隊提供了很多輔助工具幫助開發人員進行重建索引

步驟

  1. nba取一個別名nba_latest,nba_latest作為對外使用
  2. 新增一個索引nba_20200810,結構複製於nba索引,根據業務要求修改欄位
  3. 將nba資料同步至nba_20200810
  4. 給nba_20200810新增別名nba_latest,刪除此處nba別名nba_latest
  5. 刪除nba索引

 

PUT /nba_20220810
{
  "mappings": {
    "properties": {
      "age": {
        "type": "integer"
      },
      "birthDay": {
        "type": "date"
      },
      "birthDayStr": {
        "type": "keyword"
      },
      "code": {
        "type": "text"
      },
      "country": {
        "type": "keyword"
      },
      "countryEn": {
        "type": "keyword"
      },
      "displayAffiliation": {
        "type": "text"
      },
      "displayName": {
        "type": "text"
      },
      "displayNameEn": {
        "type": "text"
      },
      "draft": {
        "type": "long"
      },
      "heightValue": {
        "type": "float"
      },
      "jerseyNo": {
        "type": "keyword"
      },
      "playYear": {
        "type": "long"
      },
      "playerId": {
        "type": "keyword"
      },
      "position": {
        "type": "text"
      },
      "schoolType": {
        "type": "text"
      },
      "teamCity": {
        "type": "text"
      },
      "teamCityEn": {
        "type": "text"
      },
      "teamConference": {
        "type": "keyword"
      },
      "teamConferenceEn": {
        "type": "keyword"
      },
      "teamName": {
        "type": "keyword"
      },
      "teamNameEn": {
        "type": "keyword"
      },
      "weight": {
        "type": "text"
      }
    }
  }
}

將舊索引資料copy到新索引

同步等待,介面將會在reindex結束後返回

 

POST /_reindex
{
  "source": {
    "index": "nba"
  },
  "dest": {
    "index": "nba_20220810"
  }
}

非同步執行,如果reindex時間過長,建議加上“wait_for_completion=false”的引數條件,這樣reindex將直接返回taskId

POST /_reindex?wait_for_completion=false
{
  "source": {
    "index": "nba"
  },
  "dest": {
    "index": "nba_20220810"
  }
}

替換別名

 

POST /_aliases
{
  "actions": [
    {
      "add": {
        "index": "nba_20220810",
        "alias": "nba_latest"
      }
    },
    {
      "remove": {
        "index": "nba",
        "alias": "nba_latest"
      }
    }
  ]
}

刪除舊索引

DELETE /nba

通過別名訪問新索引

 

POST /nba_latest/_search
{
  "query": {
    "match": {
      "displayNameEn": "james"
    }
  }
}

ES之refresh操作

理想的搜尋

  新的資料一新增到索引中立馬就能搜尋到,但是真實情況不是這樣的

我們使用鏈式命令請求,先新增一個文件,再立刻搜尋

curl -X PUT 192.168.199.170:9200/star/_doc/888 -H 'Content-Type:
application/json' -d '{ "displayName": "蔡徐坤" }'
curl -X GET localhost:9200/star/_doc/_search?pretty

強制重新整理

curl -X PUT 192.168.199.170:9200/star/_doc/666?refresh -H 'Content-Type:
application/json' -d '{ "displayName": "楊超越" }'
curl -X GET localhost:9200/star/_doc/_search?pretty

修改預設更新時間(預設時間是1s)

PUT /star/_settings
{
  "index": {
    "refresh_interval": "5s"
  }
}

將refresh關閉

PUT /star/_settings
{
  "index": {
    "refresh_interval": "-1"
  }
}

ES之高亮查詢

前言

  如果返回的結果集中很多符合條件的結果,那怎麼能一眼就能看到我們想要的那個結果呢?比如下面網站所示的那樣,我們搜尋“科比”,在結果集中,將所有“科比”高亮顯示?

 

高亮查詢

 

POST /nba_latest/_search
{
  "query": {
    "match": {
      "displayNameEn": "james"
    }
  },
  "highlight": {
    "fields": {
      "displayNameEn": {}
    }
  }
}

自定義高亮查詢

POST /nba_latest/_search
{
  "query": {
    "match": {
      "displayNameEn": "james"
    }
  },
  "highlight": {
    "fields": {
      "displayNameEn": {
        "pre_tags": [
          "<h1>"
        ],
        "post_tags": [
          "</h1>"
        ]
      }
    }
  }
}

ES之查詢建議

查詢建議是什麼

  查詢建議:是為了給使用者提供更好的搜尋體驗。包括:詞條檢查,自動補全

詞條檢查

 

自動補全

 

Suggester

  • Term suggester
  • Phrase suggester
  • Completion suggester

欄位

text 指定搜尋文字
field 獲取建議詞的搜尋欄位
analyzer 指定分詞器
size 每個詞返回的最大建議詞數
sort

如何對建議詞進行排序,可用選項:

score:先按評分排序、再按文件頻率排、term順序

frequency:先按文件頻率排,再按評分,term順序排

suggest_mode

建議模式,控制提供建議詞的方式:

missing:僅在搜尋的詞項在索引中不存在時才提供建議詞,預設值;

popular:僅建議文件頻率比搜尋詞項高的詞

always:總是提供匹配的建議詞

Term Suggester

  term詞條建議器,對給輸入的文字進行分詞,為每個分詞提供詞項建議

POST /nba_latest/_search
{
  "suggest": {
    "my-suggestion": {
      "text": "jamse hardne",
      "term": {
        "suggest_mode": "missing",
        "field": "displayNameEn"
      }
    }
  }
}

Phrase suggester

  phrase短語建議,在term的基礎上,會考量多個term之間的關係,比如是否同時出現在索引的原文裡,相鄰成都,以及詞頻等

POST /nba_latest/_search
{
  "suggest": {
    "my-suggestion": {
      "text": "jamse harden",
      "phrase": {
        "field": "displayNameEn"
      }
    }
  }
}

Completion suggester

  Completion完成建議

POST /nba_latest/_search
{
  "suggest": {
    "my-suggestion": {
      "text": "Miam",
      "completion": {
        "field": "teamCityEn"
      }
    }
  }
}

 

相關文章