日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[Elasticsearch] 全文搜索 (一) - 基础概念和match查询

發布時間:2025/3/20 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Elasticsearch] 全文搜索 (一) - 基础概念和match查询 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

全文搜索(Full Text Search)

現在我們已經討論了搜索結構化數據的一些簡單用例,是時候開始探索全文搜索了 - 如何在全文字段中搜索來找到最相關的文檔。

對于全文搜索而言,最重要的兩個方面是:

相關度(Relevance)

查詢的結果按照它們對查詢本身的相關度進行排序的能力,相關度可以通過TF/IDF,參見什么是相關度,地理位置的鄰近程度(Proximity to a Geo-location),模糊相似性(Fuzzy Similarity)或者其它算法進行計算。

解析(Analysis)

解析用來將一塊文本轉換成單獨的,規范化的詞條(Tokens),參見解析和解析器(Analysis and Analyzers),用來完成:(a)倒排索引(Inverted Index)的創建;(b)倒排索引的查詢。

一旦我們開始討論相關度或者解析,也就意味著我們踏入了查詢(Query)的領域,而不再是過濾器(Filter)。

?

?

基于詞條(Term-based)和全文(Full-text)

?

盡管所有的查詢都會執行某種程度的相關度計算,并不是所有的查詢都存在解析階段。除了諸如bool或者function_score這類完全不對文本進行操作的特殊查詢外,對于文本的查詢可以被劃分兩個種類:

基于詞條的查詢(Term-based Queries)

類似term和fuzzy的查詢是不含有解析階段的低級查詢(Low-level Queries)。它們在單一詞條上進行操作。一個針對詞條Foo的term查詢會在倒排索引中尋找該詞條的精確匹配(Exact term),然后對每一份含有該詞條的文檔通過TF/IDF進行相關度_score的計算。

尤其需要記住的是term查詢只會在倒排索引中尋找該詞條的精確匹配 - 它不會匹配諸如foo或者FOO這樣的變體。它不在意詞條是如何被保存到索引中。如果你索引了["Foo", "Bar"]到一個not_analyzed字段中,或者將Foo Bar索引到一個使用whitespace解析器的解析字段(Analyzed Field)中,它們都會在倒排索引中得到兩個詞條:"Foo"以及"Bar"。

全文查詢(Full-text Queries)

類似match或者query_string這樣的查詢是高級查詢(High-level Queries),它們能夠理解一個字段的映射:

  • 如果你使用它們去查詢一個date或者integer字段,它們會將查詢字符串分別當做日期或者整型數。
  • 如果你查詢一個精確值(not_analyzed)字符串字段,它們會將整個查詢字符串當做一個單獨的詞條。
  • 但是如果你查詢了一個全文字段(analyzed),它們會首先將查詢字符串傳入到合適的解析器,用來得到需要查詢的詞條列表。

一旦查詢得到了一個詞條列表,它就會使用列表中的每個詞條來執行合適的低級查詢,然后將得到的結果進行合并,最終產生每份文檔的相關度分值。

我們會在后續章節中詳細討論這個過程。


在很少的情況下,你才需要直接使用基于詞條的查詢(Term-based Queries)。通常你需要查詢的是全文,而不是獨立的詞條,而這個工作通過高級的全文查詢來完成會更加容易(在內部它們最終還是使用的基于詞條的低級查詢)。

如果你發現你確實需要在一個not_analyzed字段上查詢一個精確值,那么考慮一下你是否真的需要使用查詢,而不是使用過濾器。

單詞條查詢通常都代表了一個二元的yes|no問題,這類問題通常使用過濾器進行表達更合適,因此它們也能夠得益于過濾器緩存(Filter Caching):

GET /_search {"query": {"filtered": { "filter": { "term": { "gender": "female" } } } } }

?

?

match查詢

?

在你需要對任何字段進行查詢時,match查詢應該是你的首選。它是一個高級全文查詢,意味著它知道如何處理全文字段(Full-text,?analyzed)和精確值字段(Exact-value,not_analyzed)。

即便如此,match查詢的主要使用場景仍然是全文搜索。讓我們通過一個簡單的例子來看看全文搜索時如何工作的。

索引一些數據

首先,我們會創建一個新的索引并通過bulk?API索引一些文檔:

DELETE /my_index PUT /my_index { "settings": { "number_of_shards": 1 }} POST /my_index/my_type/_bulk { "index": { "_id": 1 }} { "title": "The quick brown fox" } { "index": { "_id": 2 }} { "title": "The quick brown fox jumps over the lazy dog" } { "index": { "_id": 3 }} { "title": "The quick brown fox jumps over the quick dog" } { "index": { "_id": 4 }} { "title": "Brown fox brown dog" }

注意到以上在創建索引時,我們設置了number_of_shards為1:在稍后的相關度壞掉了(Relevance is broken)一節中,我們會解釋為何這里創建了一個只有一個主分片(Primary shard)的索引。

單詞查詢(Single word query)

第一個例子我們會解釋在使用match查詢在一個全文字段中搜索一個單詞時,會發生什么:

GET /my_index/my_type/_search {"query": {"match": { "title": "QUICK!" } } }

ES會按照如下的方式執行上面的match查詢:

  • 檢查字段類型

    title字段是一個全文字符串字段(analyzed),意味著查詢字符串也需要被分析。

  • 解析查詢字符串

    查詢字符串"QUICK!"會被傳入到標準解析器中,得到的結果是單一詞條"quick"。因為我們得到的只有一個詞條,match查詢會使用一個term低級查詢來執行查詢。

  • 找到匹配的文檔

    term查詢會在倒排索引中查詢"quick",然后獲取到含有該詞條的文檔列表,在這個例子中,文檔1,2,3會被返回。

  • 對每份文檔打分

    term查詢會為每份匹配的文檔計算其相關度分值_score,該分值通過綜合考慮詞條頻度(Term Frequency)("quick"在匹配的每份文檔的title字段中出現的頻繁程度),倒排頻度(Inverted Document Frequency)("quick"在整個索引中的所有文檔的title字段中的出現程度),以及每個字段的長度(較短的字段會被認為相關度更高)來得到。參考什么是相關度(What is Relevance?)

  • 這個過程會給我們下面的結果(有省略):

    "hits": [{"_id": "1", "_score": 0.5, "_source": { "title": "The quick brown fox" } }, { "_id": "3", "_score": 0.44194174, "_source": { "title": "The quick brown fox jumps over the quick dog" } }, { "_id": "2", "_score": 0.3125, "_source": { "title": "The quick brown fox jumps over the lazy dog" } } ]

    文檔1最相關,因為它的title字段短,意味著quick在它所表達的內容中占比較大。 文檔3比文檔2的相關度更高,因為quick出現了兩次。

    總結

    以上是生活随笔為你收集整理的[Elasticsearch] 全文搜索 (一) - 基础概念和match查询的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。