主頁 > 資料庫 > 看完這篇還不會 Elasticsearch 搜索,那我就哭了!

看完這篇還不會 Elasticsearch 搜索,那我就哭了!

2020-09-13 08:48:19 資料庫

本文主要介紹 ElasticSearch 搜索相關的知識,首先會介紹下 URI Search 和 Request Body Search,同時也會學習什么是搜索的相關性,如何衡量相關性,

Search API

我們可以把 ES 的 Search API 分為兩大類,第一類是 URI Search,用 HTTP GET 的方式在 URL 中使用查詢引數已達到查詢的目的;另一類為 Request Body Search,可以使用 ES 提供的基于 JSON 格式的格式更加完備的查詢語言 Query DSL(Domain Specific Language)

語法 范圍
/_search 集群上所有的索引
/jvm/_search jvm
/jvm,sql/_search jvm 和 sql
/jvm*/_search 以 jvm 開頭的索引

在查詢的時候需要通過 _search 來標明這個請求為搜索請求,同時可以指定 index,也可以指定多個 index,也可以使用通配符的方式對 index 進行搜索,

下面來看下 URI Search:

GET /users/_search?q=username:wupx

URI Search 使用的是 GET 方式,其中 q 指定查詢陳述句,語法為 Query String Syntax,是 KV 鍵值對的形式;上面的請求表示對 username 欄位進行查詢,查詢包含 wupx 的所有檔案,

URI Search 有很多引數可以指定,除了 q 還有如下引數:

  • df:默認欄位,不指定時會對所有欄位進行查詢
  • sort:根據欄位名排序
  • from:回傳的索引匹配結果的開始值,默認為 0
  • size:搜索結果回傳的條數,默認為 10
  • timeout:超時的時間設定
  • fields:只回傳索引中指定的列,多個列中間用逗號分開
  • analyzer:當分析查詢字串的時候使用的分詞器
  • analyze_wildcard:通配符或者前綴查詢是否被分析,默認為 false
  • explain:在每個回傳結果中,將包含評分機制的解釋
  • _source:是否包含元資料,同時支持 _source_includes_source_excludes
  • lenient:若設定為 true,欄位型別轉換失敗的時候將被忽略,默認為 false
  • default_operator:默認多個條件的關系,AND 或者 OR,默認為 OR
  • search_type:搜索的型別,可以為 dfs_query_then_fetchquery_then_fetch,默認為 query_then_fetch

在了解了基本的查詢引數后,讓我們先來看下什么是指定欄位查詢和什么是泛查詢?

比如 GET /movies/_search?q=2012&df=title 這個例子就是指定欄位查詢,同樣 GET /movies/_search?q=title:2012 也可以達到指定欄位查詢的目的,

再舉一個泛查詢的例子 GET /movies/_search?q=2012,會對所有欄位進行查詢,

接下來,看下什么是 Term QueryPhrase Query

比如:Beautiful Mind 等效于 Beautiful OR Mind"Beautiful Mind"等效于 Beautiful AND Mind,另外還要求前后順序保存一致,

當為 Term Query 的時候,就需要把這兩個詞用括號括起來,請求為 GET /movies/_search?q=title:(Beautiful Mind),意思就是查詢 title 中包括 Beautiful 或者 Mind

當為 Phrase Query 的時候就需要用引號包起來,請求為 GET /movies/_search?q=title:"Beautiful Mind"

另外還支持布爾操作,比如 AND(&&)、OR(||)、NOT(!),需要注意大寫,不能小寫,

在這里舉一個 NOT 的例子:GET /movies/_search?q=title:(Beautiful NOT Mind),這個請求表示查詢 title 中必須包括 Beautiful 不能包括 Mind 的檔案,

URI Search 還包括一些范圍查詢數學運算子號,比如指定電影的年份大于 1994:GET /movies/_search?q=year:>=1994

URI Search 還支持通配符查詢(查詢效率低,占用記憶體大,不建議使用,特別是放在最前面),還支持正則運算式,以及模糊匹配近似查詢

URI Search 好處就是操作簡單,只要寫個 URI 就可以了,方便測驗,但是 URI Search 只包含一部分查詢語法,不能覆寫所有 ES 支持的查詢語法

因此讓我們來看下 Request Body Search:

在 ES 中一些高階用法只能在 Request Body 里做,所以我們盡量使用 Request Body Search,它支持 GET 和 POST 方式對索引進行查詢,需要指定操作的索引名稱,同樣也要通過 _search 來標明這個請求為搜索請求,我們可以在請求體中使用 ES 提供的 DSL,下面這個例子就是簡單的 Query DSL:

POST /users/_search
{
	"query": {
		"match_all": {}
	}
}

上面的請求的意思就是把所以的結果都回傳,

也可以在 Request Body 中加入 fromsize 引數以達到分頁的效果:

POST /movies/_search
{
  "from":10,
  "size":20,
  "query":{
    "match_all": {}
  }
}

默認 from 從 0 開始,回傳 10 個結果,獲取靠后的翻頁成本較高,

如果想對搜索的結果排序也可以在請求體中加上 sort 引數:

POST /movies/_search
{
  "sort":[{"year":"desc"}],
  "query":{
    "match_all": {}
  }
}

最好在“數字型”與“日期型”欄位上排序,因為對于多值型別或者分析過的欄位排序,系統會選一個值,無法得知該值,

如果 _source 的資料量比較大,有些欄位也不需要拿到這個資訊,那么就可以對它的 _source 進行過濾,把需要的資訊加到 _source 中,比如以下請求就是 _source 中只回傳 title

POST /movies/_search
{
  "_source":["title"],
  "query":{
    "match_all": {}
  }
}

如果 _source 沒有存盤,那就只回傳匹配的檔案的元資料,同時 _source 也支持使用通配符,

接下來介紹下腳本欄位,腳本欄位可以使用 ES 中的 painless 的腳本去算出一個新的欄位結果,

GET /movies/_search
{
  "script_fields": {
    "new_field": {
      "script": {
        "lang": "painless",
        "source": "doc['year'].value+'_hello'"
      }
    }
  },
  "query": {
    "match_all": {}
  }
}

這個例子中就使用 painless 把電影的年份和 _hello 進行拼接形成一個新的欄位 new_field

在上面我們剛介紹了在 URI Search 中的 Term QueryPhrase Query,接下來讓我們看下 Request Body 中是怎么做的吧!

在此之前先來插播一條小知識-欄位類查詢,欄位類查詢主要包括以下兩類:

  • 全文匹配:針對 text 型別的欄位進行全文檢索,會對查詢陳述句先進行分詞處理,如 match,match_phrase 等 query 型別
  • 單詞匹配:不會對查詢陳述句做分詞處理,直接去匹配欄位的倒排索引,如 term,terms,range 等 query 型別

好了,現在我們來接著往下看,

可以在 Request Body 中使用在 query match 的方式把資訊填在里面,我們先來看下 Match Query,比如下面這個例子,填入兩個單詞,默認是 wupx or huxy 的查詢條件,如果想查詢兩者同時出現,可以通過加 "operator": "and" 來實作,

POST /users/_search
{
  "query": {
    "match": {
      "title": "wupx huxy"
      "operator": "and"
    }
  }
}

我們通過一張圖來看下 Match Query 的流程:

首先對查詢陳述句進行分詞,分成 wupxhuxy 兩個 Term,然后 ES 會拿到 username 的倒排索引,對 wupxhuxy 去進行匹配的算分,比如 wupx 對應的檔案是 1 和 2,huxy 對應的檔案為 1,然后 ES 會利用算分演算法(比如 TF/IDF 和 BM25,BM25 模型 5.x 之后的默認模型)列出檔案跟查詢的匹配得分,然后 ES 會對 wupx huxy 的檔案的得分結果做一個匯總,最終根據得分排序,回傳匹配檔案,

Request Body 中還支持 Match Phrase 查詢,但在 query 條件中的詞必須順序出現的,可以通過 slop 引數控制單詞間的間隔,比如加上 "slop" :1,表示中間可以有一個其他的字符,

POST /movies/_search
{
  "query": {
    "match_phrase": {
      "title":{
        "query": "one love"
        "slop":1
      }
    }
  }
}

了解完 Match Query,讓我們再來看下 Term Query:

如果不希望 ES 對輸入陳述句作分詞處理的話,可以用 Term Query,將查詢陳述句作為整個單詞進行查詢,使用方法和 Match 類似,只需要把 match 換為 term 就可以了,如下所示:

POST /users/_search
{
  "query": {
    "term": {
        "username":"wupx"
    }
  }
}

Terms Query 顧名思義就是一次可以傳入多個單詞進行查詢,關鍵詞是 terms,如下所示:

POST /users/_search
{
  "query": {
    "terms": {
      "username": [
        "wupx",
        "huxy"
      ]
    }
  }
}

另外 DSL 還支持特定的 Query String 的查詢,比如指定默認查詢的欄位名 default_field 就和前面介紹的 df 是一樣的,在 query 中也可以使用 AND 來實作一個與的操作,

POST users/_search
{
  "query": {
    "query_string": {
      "default_field": "username",
      "query": "wupx AND huxy"
    }
  }
}

下面來看下 Simple Query String Query,它其實和 Query String 類似,但是會忽略錯誤的查詢語法,同時只支持部分查詢語法,不支持 AND OR NOT,會當作字串處理,Term 之間默認的關系是 OR,可以指定 default_operator 來實作 AND 或者 OR,支持用 + 替代 AND,用 | 替代 OR,用 - 替代 NOT,

下面這個例子就是查詢 username 欄位中同時包含 wupx 的請求:

{
  "query": {
    "simple_query_string": {
      "query": "wu px",
      "fields": ["username"],
      "default_operator": "AND"
    }
  }
}

到此為止,我們就對 DSL 做了個簡單介紹,更高階的 DSL 會在以后的文章中進行介紹,

然后,我們來看下請求后回傳的結果 Response 長什么樣吧!

Response

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.9808292,
    "hits" : [
      {
        "_index" : "users",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.9808292,
        "_source" : {
          "username" : "wupx",
          "age" : "18"
        }
      }
    ]
  }
}

其中 took 表示花費的時間;total 表示符合條件的總檔案數;hits 為結果集,默認是前 10 個檔案;_index 為索引名;_id 為檔案 id;_score 為相關性評分;_source 為檔案的原始資訊,

搜索的相關性(Relevance)

那么我們平時在搜索的時候,比如輸入小米手機,會回傳很多結果,從用戶角度關心的有:是否找到所有相關的內容,有多少不相關的內容被回傳了,比如輸入的小米手機的時候不應該回傳糧食的小米給用戶,同時檔案應該按照打分的方式進行排序,也就是搜索結果中的 _score,另外,搜索引擎需要結合業務需求,平衡結果排名,

如何評估相關性?

在資訊檢索學中對相關性是有指標去評估的,第一個是查準率(Precision),具體含義是盡可能回傳較少的無關檔案給用戶;第二個為查全率(Recall),也就是盡量回傳較多的相關檔案;第三個為是否能夠按照相關度進行排序(Ranking)

下面通過一張圖來對查準率和查全率有一個更形象的理解:

其中黃色的三角形代表不相關的內容,綠色的圓代表相關的內容;在搜索結果中,黃色的三角形起名為 False Positive(納偽,簡寫 fp),通常稱作誤報,綠色的圓起名為 True Positive(納真,簡寫 tp);在沒有被搜索到的范圍中,綠色的圓的起名為 False Negatives(去真,簡寫 fn),也常稱作漏報,黃色的三角形起名為 True Negative(去偽,簡寫 tn)

那么我們可以得到:

  • 查準率等于正確的搜索結果除以全部回傳的結果,即 Precision = tp / ( tp + fp )
  • 查全率等于正確的搜索結果除以所有應該回傳的結果,即 Recall = tp / ( tp + fn )

在 ES 中提供了許多的查詢相關引數來改善搜索的 Precision 和 Recall,

總結

本文主要簡單介紹了 ES Search API 的兩種形式,學習了 URI Search 的基本方法,還學習了 Term Search 和 Phrase Search 的區別,同時介紹了什么叫搜索相關性,以及如何評估相關性,

參考文獻

《Elasticsearch技術決議與實戰》

Elastic Stack從入門到實踐

Elasticsearch頂尖高手系列

Elasticsearch核心技術與實戰

https://www.elastic.co/guide/en/elasticsearch/reference/7.1/search.html

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/22758.html

標籤:大數據

上一篇:求助:產品和毛坯資料匹配查詢問題

下一篇:sql server 陳述句問題

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more