DSL搜索

目錄

 

請求參數的查詢(QueryString)

DSL基本語法

1.分頁

2.term精確搜索與match分詞搜索

 4.terms 多個詞語匹配檢索

5.match_phrase 短語匹配

 6.match(operator)/ids

7- multi_match/boost(權重)

8.布爾查詢:可以組合多重查詢

9.過濾器

10.高亮highlight

11.refix-fuzzy-wildcard

12.深度分頁

13.scroll 滾動搜索

14.批量查詢mget

15.批量操作 bulk


請求參數的查詢(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"}}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章