ElasticSearch (ES)學習之路(五)ES 複雜搜索( 匹配 過濾 精準 排序 高亮)

ElasticSearch (ES)學習之路(五)ES 複雜搜索( 匹配 過濾 精準 排序 高亮)

在上文中,我們查詢小紅 其kinbana 語法是這樣寫的

GET /lei/one/_search?q=name:小麗

image-20200705145720805

前文中,也是做了分析,由於有多個包含‘小麗’的數據,所以我們在搜索’小麗’ 時將與之相匹配的數據全部搜索了出來,並且 ,搜索出的每條數據都包含了一個_score 分值字段

其實質意義:_score=分值=匹配度 結果匹配度越高 分值則越高,則排名越是考前


在實際查詢語法時候,我們大多不會寫q=xxxxx ,而是寫查詢參數體 類似於 添加數據時的請求體,其查詢語法如下

GET /索引名/類型名/_search
{
  "query":{
  	"查詢參數體 查詢條件"
  }
}

例如,我們還是接着 查詢小麗的例子進行編寫

單條件查詢

使用kinbanna的好處,語法可以提示 如下 field 列名 match 匹配

image-20200705150435473

GET /lei/one/_search
{
  "query": {
    "match": {
      "name": "小麗"
    }
  }
}

此操作就對應着我們開始編寫的一行 語句 GET /lei/one/_search?q=name:小麗 ,只是更具有層次性,可讀性更好,看,查詢結果也是一模一樣的。 這裏匹配是什麼意思呢 就是隻要包含小麗的就算匹配 小麗 小麗2 都會命中

image-20200705151303654

這個hits 就是查詢出的結果集對象,其中即包含了文檔數以及索引信息概括,以及包含了每個具體的文檔數據

image-20200705150555209

查詢結果字段過濾

何爲結果字段過濾呢?我們在寫sql語句的時候,可以select * ,也可以select 列1,列2 , 根據我們select 的不同,返回不同的字段信息

那麼在es 中也是有這個功能的

例如,在上方查詢結果的,我們發現文檔中的 三個字段 name age birthday 都被查詢出來了

本文當前呢,爲了演示,字段則返回 name age

GET /lei/one/_search
{
  "query": {
    "match": {
      "name": "小麗"
    }
  }
  , "_source": ["name","age"]
}

image-20200705152446036

分頁

爲什麼要分頁,,,我這裏就不用細說了吧(都學到es了,還不懂爲啥要分頁,那切雀雀吧)

由於我這裏只有兩條數據哈,所以分頁呢,暫時一頁一條即可

GET /lei/one/_search
{
  "query": {
    "match": {
      "name": "小麗"
    }
  }
  , "_source": ["name","age"]
  ,"from": 0
  , "size": 1
}

from =(當前頁-1)*每頁長度

size= 每頁長度(即每頁要展示的長度)

注意的是.from size 都是與query爲同級

image-20200705153247354

image-20200705153509445

排序

由於我之前添加文檔一個採用了put指定_id,一個採用post 隨機生成_ _ id ,我這裏故採用年齡進行排序吧

排序,只需要在與 query同級別下 輸入"sort" 其Kinbanba 就會自動幫我們補全 排序語法

GET /lei/one/_search
{
  "query": {
    "match": {
      "name": "小麗"
    }
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ]
}

image-20200705153815443

多條件匹配查詢

等價於 sql 中 where xxx =?? and xxx=?? 查詢名字爲小麗 並且年齡爲22歲

and

must 必須的意思 等價於 and 條件

GET /lei/one/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "小麗"
          }
        },
        {
           "match": {
            "age": "22"
          }
        }
      ]
    }
  }
}

image-20200705155155049

or

等價於 sql 中 where xxx =?? or xxx=?? 查詢名字爲小麗 或者年齡爲222歲

or 條件 很簡單 將上方的 must 改爲 should (應該 )

should 應該的意思 等價於or 條件 拼接

GET /lei/one/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "name": "小麗"
          }
        },
        {
           "match": {
            "age": "222"
          }
        }
      ]
    }
  }
}

image-20200705155547728

新增字段

查詢某列中的值 包含xxx的數據 可以是數組中某一元素值等等 (我先前準備的數據沒有哈,所以這裏添加一個列,並添加一些數據)

POST /lei/one
{
     "properties": {
        "hobby": {
            "type": "array"
        }
    }
}
POST /lei/one/2/_update
{
  "doc":{
    "hobby":["籃球","擊劍"]
  }
}
POST /lei/one/7ErnHHMBjoLvVc_LTjx_/_update
{
  "doc":{
    "hobby":["足球","爬山"]
  }
}

查詢某列中 包含XXX 的文檔信息

查詢某列中 包含某些值得文檔 查詢時 “列名”:" 包含的值 多個用空格隔開"

等價於 mysql 中 where xxx like “xxx”

我們可以看到 匹配度越高 其分值越高 排名也是靠前

image-20200705162246270

!= 條件查詢

不等於 等價於msql中的 where xxx!= ??

我這裏查詢年齡不爲222歲

GET /lei/one/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
           "match": {
            "age": "222"
          }
        }
      ]
    }
  }
}

image-20200705155815592

條件過濾

此方法與 where and 語法類似 但是 不同的是 其可以做大小於等一些邏輯判斷 must 的話,僅僅只表示=匹配

語法解釋 : 查詢匹配名爲小麗 並且 年齡大於等於30 where name=‘小麗’ and age >=30

GET /lei/one/_search
{
  "query": {
    "bool": {
      "must": [
        {
           "match": {
            "name": "小麗"
          }
        }
      ],
      "filter": {
        "range": {
          "age": {
            "gte": 30
          }
        }
      }
    }
  }
}

image-20200705160359102

還可以區間過濾 ,例如 查詢名字爲小麗 且年齡在22-30之間

image-20200705160741964

精確查詢

trem 精確查詢 與match匹配不同 只會查詢其精確到具體的條件

新建索引庫 並插入數據

PUT /tremdb
{
  "mappings": {
    "properties": {
      "name":{
        "type": "keyword"
      },
      "desc":{
        "type": "text"
      }
    }
  }
}
PUT /tremdb/_doc/1
{
  "name":"曹操魏武帝",
  "desc":"魏武帝,愛人妻,三國"
}
PUT /tremdb/_doc/2
{
  "name":"劉備漢昭烈帝",
  "desc":"漢昭烈帝,人稱大耳賊,三國"
}
PUT /tremdb/_doc/3
{
  "name":"孫權吳大帝",
  "desc":"吳大帝,江東小霸王之弟,三國"
}

我們先前也講過 keyword 是不會被分詞的 那麼我們這裏可以測試一下

我們以名字作爲精確搜索,“帝” 沒有結果

image-20200705170243125

以武帝 作爲精確搜索條件----還是未命中

image-20200705170353553

以曹操魏武 爲精確搜索條件 ----還是未命中

image-20200705170453816

以曹操魏武帝 爲精確搜索條件 ----命中

image-20200705170523597

可以得出結論 字段類型爲keyword 的時候 ,其不會被分詞器進行解析 只有以完整的值進行查詢纔會被命中


測試desc text 類型 text 會被分詞 包含 帝 所以我們以帝 進行查詢 則能獲取到結果

image-20200705170644049

精確查詢多個

image-20200705171152861

高亮顯示

高亮,在搜索網站時 很常見 ,例如,我們的京東 /百度

搜一波 外星人 可以看到 外星人關鍵字 全部高亮顯示了,那麼是怎麼做到的呢??

image-20200705172225918

高亮!

image-20200705172015503

可以看到 我搜索的小麗 結果 都添加了一個高亮字段 並用 標籤包裹起來了,這就是高亮!

可能有人想問,高亮 爲什麼呢 ?別人都是紅色的 ,我也想要!

可以,這個需求可以做的!

自定義高亮顏色

es 高亮 是支持我們自定義顏色的! 如何自定義呢 注意兩個json 字段的使用!

"pre_tags": "<font color=red>",  前綴
"post_tags": "</font>",   後綴

設置這兩個標籤後呢,其搜索的高亮 將會被前後綴包裹

完整查詢語句:

注意,我這裏定義了 標籤,爲了在 typora 以及csdn 上直接顯示

GET /lei/one/_search
{
  "query": {
    "bool": {
      "must": [
        {
           "match": {
            "name": "小麗"
          }
        }
      ]
    }
  },
  "highlight": {
    "pre_tags": "<font color=red>",
    "post_tags": "</font>", 
    "fields": {
      "name":{}
    }
  }
}

image-20200705173319019

image-20200705173338941

基本的ES 語法差不多就到這裏了! 後續隨着學習的深度不斷添加 !!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章