本節主要講解 Elasticsearch 的 搜索相關功能 Search-API,講解什么是 URL Search 和 Request Body Search 的語法,對常用的語法都會一一進行詳細介紹。
1.Search API
Search API 分為兩大類一個是 URL Search 和 Request Body Search。
-
URL Search
- 在 URL 中根據參數查詢結果
-
Request Body Search
- 一種基於 JSON 格式的查詢語言 Query Domain Specific Language (DSL)
2.URL Search
GET /movies/_search?q=love&df=title&sort=year:desc&from=0&size=10&timeout=1s
{
"profile":"true"
}
- q 指定查詢語句
- df 指定查詢字段,不指定對所有字段進行查詢
- Sort 排序
- from 和 size 用於分頁
- 如果要查詢執行過程,可以增加 profile 為 true
2.1Query String Syntax
2.1.1TermQuery
GET /movies/_search?q=title:(Beautiful Mind)
{
"profile":"true"
}
輸出為有 Beautiful 或者 Mind 的電影名稱
2.1.2PhraseQuery
GET /movies/_search?q=title:"Beautiful Mind"
{
"profile":"true"
}
輸出為按照順序同時出現 "Beautiful Mind" 這個詞語的電影名稱
TermQuery 必須帶有 () ,比如 (Beautiful Mind),不帶的情況是不一樣的。
GET /movies/_search?q=title:(Beautiful Mind)
Mind 為泛查詢,對所有字段都進行查詢
2.1.3布爾查詢
- AND / OR / NOT 或者 && /|| / !
- 必須大寫
- title:(Beautiful OR Mind)
GET /movies/_search?q=title:(Beautiful OR Mind)
{
"profile":"true"
}
里面執行是 BooleanQuery,最后還是以 TermQuery 進行分組查詢。
2.1.4范圍查詢
- [] 為閉區間,{} 為開區間
- year:[2018 TO 2019],查詢時間在2018-2019年的電影
GET /movies/_search?q= year:[2018 TO 2019]
{
"profile":"true"
}
2.1.5算數查詢
- year:>=2018,匹配電影在2018年以后的電影
GET /movies/_search?q=year:>=2018
{
"profile":"true"
}
2.1.6通配符和正則匹配
- ? 代表1個字符,*代表0到多個字符,這種不推薦,占用太多空間
- title:b*,匹配電影名稱有 b 開頭的名稱
- title:[bu],匹配電影名稱有 b 開頭的名稱
GET /movies/_search?q=title:b*
2.1.7模糊查詢
- "Avengers War"~2 ,Avengers 和 War 之間有兩個 term,匹配 Avengers: Infinity War - Part I,不能匹配 Avengers: War。
GET /movies/_search?q=title:"Avengers War"~2
3.Request Body Search
其實在高階使用方法上只有 Request Body Search 才能實現,所以也是推薦使用這種方法查詢學習。
Request Body Search 將查詢語句通過通過 HTTP 方式發送到 ES,進行查詢
3.1Query DSL
POST kibana_sample_data_ecommerce/_search
{
"profile": true,
"_source":["customer_first_name","customer_full_name","customer_gender"],
"from":10,
"size":20,
"sort":[{"order_date":"desc"}],
"query": {
"match_all": {}//查詢所有文檔
}
}
- from 和 size 進行分頁,"from":10,
"size":20,from 從 10 開始,返回20個結果,不填寫時from=0,size=10 - sort 根據某些字段進行排序,最好選擇日期或者數字的列進行排序
- _source 當你不需要對所有字段進行查詢,通過 _source 選擇需要展示數據,不填寫則所有,)source 支持正則
3.2腳本字段
腳本字段簡單說通過 ES 的 painless 腳本去算出一個新的字段。這個有什么用處呢?當你要對一個列排序,發現存儲的有不同的單位,需要轉換之后才能做一個統一的排序。
GET kibana_sample_data_ecommerce/_search
{
"script_fields": {
"new_field": {
"script": {
"lang": "painless",
"source": "doc['customer_id']+'_2333333!'"
}
}
},
"query": {
"match_all": {}
}
}
腳本字段不要選擇文本類型,默認禁止,可以通過設置 fielddata = true 開啟,不建議。
3.3Match 查詢表達式
前面 URL Search 中講解 Term 和 Phrase 查詢,現在我們來看在 Request Body Search 是怎么實現。
- 使用 quest-match 方式,下一層填寫具體查詢內容,
- 查詢內容兩個字符串,類似於 OR 方式。
POST movies/_search
{
"query": {
"match": {
"title": "Who Last"
}
}
}
如果你要要求 Who Last 要同時出現,增加 "operator": "and" 實現。
POST movies/_search
{
"query": {
"match": {
"title": {
"query": "Who Christmas",
"operator": "and"
}
}
}
}
3.4Match Phrase
- 通過使用 query-match_phrase 實現 Phrase 查詢
- query 的詞必須按照順序排列
- slop 實現模糊查詢,slop=1,表示中間可以有一個字符
POST movies/_search
{
"query": {
"match_phrase": {
"title": {
"query": "Who Christmas"
}
}
}
}
POST movies/_search
{
"query": {
"match_phrase": {
"title": {
"query": "Who Christmas",
"slop": 1
}
}
}
}
4.小結
本篇主要對 Search-Api 的 URL Search 和 Request Body Search 詳細介紹,URL Search 和 Request Body Search 都可以簡單方便查詢我們想要的結果, 那么我們應該采用哪種方式進行查詢呢?在簡單的進行查詢兩種方式沒有什么區別,但是在 ES 中高級使用方法只能在 Request Body Search 中做,所有這里也是推薦學習和使用這種方法,對 Request Body Search 高階使用的方法會在之后的章節進行講解。
5.數據來源
kibana_sample_data_ecommerce 索引是 kibana 自帶的索引,需要手動在 kibana 進行點擊導入
movies 索引是 movielens 數據集,通過https://grouplens.org/datasets/movielens/ 這個地址下載。通過 Logstash 導入。logstash.conf 和 數據文件在公眾號后台回復 ES 獲取。
【Elasticsearch 7 探索之路】(四)Analyzer 分析
【Elasticsearch 7 探索之路】(三)倒排索引
【Elasticsearch 7 探索之路】(二)文檔的 CRUD 和批量操作
【Elasticsearch 7 搜索之路】(一)什么是 Elasticsearch?