目錄
請求參數的查詢(QueryString)
GET /shop/_doc/_search?q=desc:慕課網
GET /shop/_doc/_search?q=nickname:慕&q=age:25
DSL基本語法
語法格式爲一個json object,內容都是key-value鍵值對,json可以嵌套。
key可以是一些es的關鍵字,也可以是某個field字段,後面會遇到
# 查詢
POST /shop/_doc/_search
{
"query": {
"match": {
"desc": "慕課網"
}
}
}
# 判斷某個字段是否存在
{
"query": {
"exists": {
"field": "desc"
}
}
}
1.分頁
POST /shop/_doc/_search
{
"query": {
"match_all": {}
},
"from": 0,
"size": 10
}
{
"query": {
"match_all": {}
},
"_source": [
"id",
"nickname",
"age"
],
"from": 5, 從第幾條數據開始
"size": 5 數據的大小
}
2.term精確搜索與match分詞搜索
- 注:match會對慕課網先進行分詞(其實就是全文檢索),在查詢,而term則不會,直接把慕課網作爲一個整的詞彙去搜索。
POST /shop/_doc/_search
{
"query": {
"term": {
"desc": "慕課網"
}
}
}
對比
{
"query": {
"match": {
"desc": "慕課網"
}
}
}
4.terms 多個詞語匹配檢索
相當於是tag標籤查詢,比如慕課網的一些課程會打上前端/後端/大數據/就業課這樣的標籤,可以完全匹配做類似標籤的查詢
POST /shop/_doc/_search
{
"query": {
"terms": {
"desc": ["慕課網", "學習", "騷年"]
}
}
}
5.match_phrase 短語匹配
match:分詞後只要有匹配就返回,match_phrase:分詞結果必須在text字段分詞中都包含,而且順序必須相同,而且必須都是連續的。(搜索比較嚴格)
slop:允許詞語間跳過的數量
POST /shop/_doc/_search
{
"query": {
"match_phrase": {
"desc": {
"query": "大學 畢業 研究生",
"slop": 2
}
}
}
}
6.match(operator)/ids
- or:搜索內容分詞後,只要存在一個詞語匹配就展示結果
- and:搜索內容分詞後,都要滿足詞語匹配
POST /shop/_doc/_search { "query": { "match": { "desc": "慕課網" } } } # 等同於 { "query": { "match": { "desc": { "query": "xbox遊戲機", "operator": "or" } } } } # 相當於 select * from shop where desc='xbox' or|and desc='遊戲機'
minimum_should_match: 最低匹配精度,至少有[分詞後的詞語個數]x百分百,得出一個數據值取整。舉個例子:當前屬性設置爲70,若一個用戶查詢檢索內容分詞後有10個詞語,那麼匹配度按照 10x70%=7,則desc中至少需要有7個詞語匹配,就展示;若分詞後有8個,則 8x70%=5.6,則desc中至少需要有5個詞語匹配,就展示。
POST /shop/_doc/_search { "query": { "match": { "desc": { "query": "女友生日送我好玩的xbox遊戲機", "minimum_should_match": "60%" } } } }
根據文檔主鍵ids搜索
-
POST /shop/_doc/_search { "query": { "ids": { "type": "_doc", "values": ["1001", "1010", "1008"] } } }
7- multi_match/boost(權重)
滿足使用match在多個字段中進行查詢的需求
POST /shop/_doc/_search
{
"query": {
"multi_match": {
"query": "皮特帕克慕課網",
"fields": ["desc", "nickname"]
}
}
}
boost:權重,爲某個字段設置權重,權重越高,文檔相關性得分就越高。通暢來說搜索商品名稱要比商品簡介的權重更高。
POST /shop/_doc/_search
{
"query": {
"multi_match": {
"query": "皮特帕克慕課網",
"fields": ["desc", "nickname^10"]
}
}
}
nickname^10 代表搜索提升10倍相關性,也就是說用戶搜索的時候其實以這個nickname爲主,desc爲輔,nickname的匹配相關度當然要提高權重比例了。
8.布爾查詢:可以組合多重查詢
- must:查詢必須匹配搜索條件,譬如 and
- should:查詢匹配滿足1個以上條件,譬如 or
- must_not:不匹配搜索條件,一個都不要滿足
POST /shop/_doc/_search { "query": { "bool": { "must": [ { "multi_match": { "query": "慕課網", "fields": ["desc", "nickname"] } }, { "term": { "sex": 1 } }, { "term": { "birthday": "1996-01-14" } } ] } } } { "query": { "bool": { "should(must_not)": [ { "multi_match": { "query": "學習", "fields": ["desc", "nickname"] } }, { "match": { "desc": "遊戲" } }, { "term": { "sex": 0 } } ] } } }
爲指定詞語加權
POST /shop/_doc/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"desc": {
"query": "律師",
"boost": 18
}
}
},
{
"match": {
"desc": {
"query": "進修",
"boost": 2
}
}
}
]
}
}
}
9.過濾器
對搜索出來的結果進行數據過濾。不會到es庫裏去搜,不會去計算文檔的相關度分數,所以過濾的性能會比較高,過濾器可以和全文搜索結合在一起使用。
post_filter元素是一個頂層元素,只會對搜索結果進行過濾。不會計算數據的匹配度相關性分數,不會根據分數去排序,query則相反,會計算分數,也會按照分數去排序。
使用場景:
- query:根據用戶搜索條件檢索匹配記錄
- post_filter:用於查詢後,對結果數據的篩選
實操:查詢賬戶金額大於80元,小於160元的用戶。並且生日在1998-07-14的用戶 - gte:大於等於
- lte:小於等於
- gt:大於
lt:小於
POST /shop/_doc/_search
{
"query": {
"match": {
"desc": "慕課網遊戲"
}
},
"post_filter": {
"range": {
"money": {
"gt": 60,
"lt": 1000
}
}
}
}
10.高亮highlight
POST /shop/_doc/_search
{
"query": {
"match": {
"desc": "慕課網"
}
},
"highlight": {
"pre_tags": ["<tag>"],
"post_tags": ["</tag>"],
"fields": {
"desc": {}
}
}
}
11.refix-fuzzy-wildcard
prefix前綴
POST /shop/_doc/_search
{
"query": {
"prefix": {
"desc": "imo"
}
}
}
fuzzy
模糊搜索,並不是指的sql的模糊搜索,而是用戶在進行搜索的時候的打字錯誤現象,搜索引擎會自動糾正,然後嘗試匹配索引庫中的數據。
POST /shop/_doc/_search
{
"query": {
"fuzzy": {
"desc": "imoov.coom"
}
}
}
# 或多字段搜索
{
"query": {
"multi_match": {
"fields": [ "desc", "nickname"],
"query": "imcoc supor",
"fuzziness": "AUTO"
}
}
}
{
"query": {
"multi_match": {
"fields": [ "desc", "nickname"],
"query": "演說",
"fuzziness": "1"
}
}
}
wildcard:
佔位符查詢。
?:1個字符 *:1個或多個字符
POST /shop/_doc/_search
{
"query": {
"wildcard": {
"desc": "*oo?"
}
}
}
{
"query": {
"wildcard": {
"desc": "演*"
}
}
}
12.深度分頁
分頁查詢
POST /shop/_doc/_search
{
"query": {
"match_all": {}
},
"from": 0,
"size": 10
}
深度分頁:深度分頁其實就是搜索的深淺度,比如第1頁,第2頁,第10頁,第20頁,是比較淺的;第10000頁,第20000頁就是很深了。
{
"query": {
"match_all": {}
},
"from": 9990,
"size": 10
}
{
"query": {
"match_all": {}
},
"from": 9999,
"size": 10
}
我們在獲取第9999條到10009條數據的時候,其實每個分片都會拿到10009條數據,然後集合在一起,總共是10009*3=30027條數據,針對30027數據再次做排序處理,最終會獲取最後10條數據。
如此一來,搜索得太深,就會造成性能問題,會耗費內存和佔用cpu。而且es爲了性能,他不支持超過一萬條數據以上的分頁查詢。那麼如何解決深度分頁帶來的性能呢?其實我們應該避免深度分頁操作(限制分頁頁數),比如最多隻能提供100頁的展示,從第101頁開始就沒了,畢竟用戶也不會搜的那麼深,我們平時搜索淘寶或者百度,一般也就看個10來頁就頂多了。
提升搜索量:通過設置index.max_result_window來突破10000數據
GET /shop/_settings
PUT /shop/_settings
{
"index.max_result_window": "20000"
}
13.scroll 滾動搜索
一次性查詢1萬+數據,往往會造成性能影響,因爲數據量太多了。這個時候可以使用滾動搜索,也就是 scroll。
滾動搜索可以先查詢出一些數據,然後再緊接着依次往下查詢。在第一次查詢的時候會有一個滾動id,相當於一個錨標記,隨後再次滾動搜索會需要上一次搜索的錨標記,根據這個進行下一次的搜索請求。每次搜索都是基於一個歷史的數據快照,查詢數據的期間,如果有數據變更,那麼和搜索是沒有關係的,搜索的內容還是快照中的數據。
https://www.elastic.co/guide/cn/elasticsearch/guide/current/scroll.html
scroll=1m,相當於是一個session會話時間,搜索保持的上下文時間爲1分鐘。
POST /shop/_search?scroll=1m
{
"query": {
"match_all": {
}
},
"sort" : ["_doc"],
"size": 5
}
POST /_search/scroll
{
"scroll": "1m",
"scroll_id" : "your last scroll_id"
}
14.批量查詢mget
http://192.168.35.132:9200/shop/_doc/_mget
{
"ids":["1001","1002"]
}
結果:"found": true表示有數據,false表示沒有數據
{
"docs": [
{
"_index": "shop",
"_type": "_doc",
"_id": "1001",
"_version": 1,
"_seq_no": 0,
"_primary_term": 1,
"found": true,
"_source": {
"id": 1001,
"age": 18,
"username": "imoocAmazing",
"nickname": "慕課網",
"money": 88.8,
"desc": "我在慕課網學習java和前端,學習到了很多知識",
"sex": 0,
"birthday": "1992-12-24",
"face": "https://www.imooc.com/static/img/index/logo.png"
}
},
{
"_index": "shop",
"_type": "_doc",
"_id": "1002",
"_version": 1,
"_seq_no": 0,
"_primary_term": 1,
"found": true,
"_source": {
"id": 1002,
"age": 19,
"username": "justbuy",
"nickname": "周杰棍",
"money": 77.8,
"desc": "今天上下班都很堵,車流量很大",
"sex": 1,
"birthday": "1993-01-24",
"face": "https://www.imooc.com/static/img/index/logo.png"
}
}
]
}
15.批量操作 bulk
bulk操作和以往的普通請求格式有區別。不要格式化json,不然就不在同一行了,這個需要注意。
action: { metadata }}\n
{ request body }\n
{ action: { metadata }}\n
{ request body }\n
{ action: { metadata }}代表批量操作的類型,可以是新增、刪除或修改
\n是每行結尾必須填寫的一個規範,每一行包括最後一行都要寫,用於es的解析
{ request body }是請求body,增加和修改操作需要,刪除操作則不需要
批量操作的類型
-create新增文檔數據,在metadata中指定index以及type
POST /_bulk
{"create": {"_index": "shop2", "_type": "_doc", "_id": "2001"}}
{"id": "2001", "nickname": "name2001"}
{"create": {"_index": "shop2", "_type": "_doc", "_id": "2002"}}
{"id": "2002", "nickname": "name2002"}
{"create": {"_index": "shop2", "_type": "_doc", "_id": "2003"}}
{"id": "2003", "nickname": "name2003"}
- create創建已有id文檔,在url中指定index和type
POST /shop/_doc/_bulk
{"create": {"_id": "2003"}}
{"id": "2003", "nickname": "name2003"}
{"create": {"_id": "2004"}}
{"id": "2004", "nickname": "name2004"}
{"create": {"_id": "2005"}}
{"id": "2005", "nickname": "name2005"}
- index創建,已有文檔id會被覆蓋,不存在的id則新增
POST /shop/_doc/_bulk
{"index": {"_id": "2004"}}
{"id": "2004", "nickname": "index2004"}
{"index": {"_id": "2007"}}
{"id": "2007", "nickname": "name2007"}
{"index": {"_id": "2008"}}
{"id": "2008", "nickname": "name2008"}
- update跟新部分文檔數據
POST /shop/_doc/_bulk
{"update": {"_id": "2004"}}
{"doc":{ "id": "3004"}}
{"update": {"_id": "2007"}}
{"doc":{ "nickname": "nameupdate"}}
- delete批量刪除
POST /shop/_doc/_bulk
{"delete": {"_id": "2004"}}
{"delete": {"_id": "2007"}}
POST /shop/_doc/_bulk
{"create": {"_id": "8001"}}
{"id": "8001", "nickname": "name8001"}
{"update": {"_id": "2001"}}
{"doc":{ "id": "20010"}}
{"delete": {"_id": "2003"}}
{"delete": {"_id": "2005"}}