国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

一起學(xué)Elasticsearch系列-Query DSL

這篇具有很好參考價(jià)值的文章主要介紹了一起學(xué)Elasticsearch系列-Query DSL。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

本文已收錄至Github,推薦閱讀 ?? Java隨想錄
微信公眾號(hào):Java隨想錄


DSL是Domain Specific Language的縮寫,指的是為特定問題領(lǐng)域設(shè)計(jì)的計(jì)算機(jī)語言。這種語言專注于某特定領(lǐng)域的問題解決,因而比通用編程語言更有效率。

在Elasticsearch中,DSL指的是Elasticsearch Query DSL,是一種以JSON形式表示的查詢語言。通過這種語言,用戶可以構(gòu)建復(fù)雜的查詢、排序和過濾數(shù)據(jù)等操作。這些查詢可以是全文搜索、聚合搜索,也可以是結(jié)構(gòu)化的搜索。

查詢上下文

搜索是Elasticsearch中最關(guān)鍵和重要的部分,使用query關(guān)鍵字進(jìn)行檢索,更傾向于相關(guān)度搜索,故需要計(jì)算評(píng)分。

在查詢上下文中,一個(gè)查詢語句表示一個(gè)文檔和查詢語句的匹配程度。無論文檔匹配與否,查詢語句總能計(jì)算出一個(gè)相關(guān)性分?jǐn)?shù)在_score字段上。

相關(guān)度評(píng)分:score

相關(guān)度評(píng)分用于對(duì)搜索結(jié)果排序,評(píng)分越高則認(rèn)為其結(jié)果和搜索的預(yù)期值相關(guān)度越高,即越符合搜索預(yù)期值,默認(rèn)情況下評(píng)分越高,則結(jié)果越靠前。在7.x之前相關(guān)度評(píng)分默認(rèn)使用TF/IDF算法計(jì)算而來,7.x之后默認(rèn)為BM25。

score是根據(jù)各種因素計(jì)算出來的,包括:

  • Term Frequency(詞頻):一個(gè)詞在文檔中出現(xiàn)的次數(shù)越多,score就越高。
  • Inverse Document Frequency(逆文檔頻率):一個(gè)詞在所有文檔中出現(xiàn)的次數(shù)越少,score就越高。
  • Field Length Norm(字段長(zhǎng)度規(guī)范):字段的長(zhǎng)度越短,score就越高。

這三個(gè)因素共同決定了score的值。然而,你也可以通過設(shè)置自定義評(píng)分或者禁用評(píng)分來影響score的計(jì)算。

TF/IDF & BM25

TF/IDF是一種在信息檢索和文本挖掘中廣泛使用的統(tǒng)計(jì)方法,用于評(píng)估一個(gè)詞語對(duì)于一個(gè)文件集或一個(gè)語料庫(kù)中的一個(gè)文件的重要程度。名稱中的TF表示“術(shù)語頻率”,IDF表示“逆向文件頻率”。

  • TF (Term Frequency) :這是衡量詞在文檔中出現(xiàn)的頻率。通常來說,一個(gè)詞在文檔中出現(xiàn)的次數(shù)越多,其重要性就可能越大。但這并不總是正確的,比如在很多英文文檔中,“the”、“and”等詞出現(xiàn)的頻率非常高,但我們并不能因此認(rèn)為它們就非常重要。因此,需要結(jié)合 IDF 來使用。
  • IDF (Inverse Document Frequency) :這是衡量詞是否常見的度量。如果某個(gè)詞在許多文檔中都出現(xiàn),那么它可能并不具有區(qū)分性,對(duì)于搜索和分類的幫助就不大。例如,每篇英文文章中都會(huì)出現(xiàn)的“the”對(duì)于區(qū)分文章內(nèi)容就沒有什么幫助。所以,如果一個(gè)詞在所有文檔中出現(xiàn)得越多,那么其 IDF 值就會(huì)越小,相反,如果一個(gè)詞很少在文檔中出現(xiàn),那么其 IDF 值就會(huì)較大。

TF-IDF 會(huì)將這兩個(gè)因子結(jié)合起來,為每個(gè)詞產(chǎn)生一個(gè)權(quán)重。具有較高 TF-IDF 分?jǐn)?shù)的詞被認(rèn)為在文檔中更重要。通過這種方式,ES 能夠提供相關(guān)性排序,使得包含用戶查詢?cè)~匯的最相關(guān)文檔排在搜索結(jié)果的前面。

BM25是一種更先進(jìn)的排名函數(shù),也是基于TF/IDF的一種改進(jìn)型方法。它引入了兩個(gè)新概念:

  • 文檔長(zhǎng)度歸一化:長(zhǎng)文檔可能會(huì)有更多的關(guān)鍵詞,但這并不意味著它與查詢更相關(guān)。BM25通過調(diào)整文檔長(zhǎng)度來解決這個(gè)問題。
  • 飽和度:在TF/IDF中,詞項(xiàng)的出現(xiàn)頻率越高,其重要性就越大。然而在實(shí)踐中,一旦一個(gè)詞在文檔中出現(xiàn)過,再次出現(xiàn)時(shí)增加的相關(guān)性可能會(huì)降低。BM25通過設(shè)置一個(gè)飽和點(diǎn)來解決這個(gè)問題,超過這個(gè)點(diǎn),詞的權(quán)重增加就會(huì)變得不那么敏感。

總結(jié)而言,BM25是TF/IDF的改進(jìn)版,通過文檔長(zhǎng)度歸一化和頻率飽和度控制來優(yōu)化搜索結(jié)果。

源數(shù)據(jù):source

_source字段包含索引時(shí)原始的JSON文檔內(nèi)容,字段本身不建立索引(因此無法進(jìn)行搜索),但是會(huì)被存儲(chǔ),所以當(dāng)執(zhí)行獲取請(qǐng)求是可以返回_source字段。

雖然很方便,但是_source字段的確會(huì)對(duì)索引產(chǎn)生存儲(chǔ)開銷,你可以通過關(guān)閉_source字段來節(jié)省空間,但這通常不建議,因?yàn)橛辛嗽紨?shù)據(jù),我們可以對(duì)數(shù)據(jù)進(jìn)行重新索引,并且在獲取數(shù)據(jù)時(shí)也更加靈活。

如果你禁用了_source字段,那么會(huì)有以下幾個(gè)影響:

  • 無法獲取原始數(shù)據(jù):當(dāng)你查詢某個(gè)文檔時(shí),你將無法獲取到原始的_source字段內(nèi)容,因?yàn)樗鼪]有被存儲(chǔ)在Elasticsearch中。
  • 更新和重新索引的問題:如果你想更新文檔或者執(zhí)行重新索引操作,可能會(huì)遇到問題,因?yàn)檫@兩種操作都需要原始的_source字段。
  • 腳本字段和某些Aggregations可能受到影響:如果你正在使用腳本字段或者依賴_source字段的Aggregations,那么禁用_source可能導(dǎo)致這些特性出問題。

下面是一些使用_source字段的例子:

  1. 在索引文檔時(shí)啟用/禁用_source
PUT my_index
{
  "mappings": {
    "_source": {
      "enabled": false
    },
    "properties": {
      "field1": { "type": "text" }
    }
  }
}

在這個(gè)例子中,新創(chuàng)建的my_index索引將不會(huì)存儲(chǔ)_source字段。

  1. 獲取文檔的_source字段:
GET /my_index/_doc/1

返回的結(jié)果中會(huì)包含_source字段。

  1. 在獲取文檔時(shí)只獲取_source字段中特定的字段:
GET /my_index/_doc/1?_source=field1,field2

在這個(gè)例子中,返回的_source字段只包含field1field2。

注意:_source字段并不用于搜索,禁用_source字段不會(huì)影響你的搜索結(jié)果。

源數(shù)據(jù)過濾

假設(shè)你的應(yīng)用只需要獲取部分字段(如"name"和"price"),而其他字段(如"desc"和"tags")不經(jīng)常使用或者數(shù)據(jù)量較大,導(dǎo)致傳輸和處理這些額外的數(shù)據(jù)會(huì)增加網(wǎng)絡(luò)開銷和處理時(shí)間。在這種情況下,通過設(shè)置includesexcludes可以有效地減少每次請(qǐng)求返回的數(shù)據(jù)量,提高效率。

例如:

PUT product
{
  "mappings": {
    "_source": {
      "includes": ["name", "price"],
      "excludes": ["desc", "tags"]
    }
  }
}

Including:結(jié)果中返回哪些field。

Excluding:結(jié)果中不要返回哪些field,Excluding優(yōu)先級(jí)比Including更高。

需要注意的是,盡管這些設(shè)置會(huì)影響搜索結(jié)果中_source字段的內(nèi)容,但并不會(huì)改變實(shí)際存儲(chǔ)在Elasticsearch中的數(shù)據(jù)。也就是說,"desc"和"tags"字段仍然會(huì)被索引和存儲(chǔ),只是在獲取源數(shù)據(jù)時(shí)不會(huì)被返回。

上述這種在mapping中定義的方式不推薦,因?yàn)閙apping不可變。我們可以在查詢過程中指定返回的字段,如下:

GET product/_search
{
  "_source": {
    "includes": ["owner.*", "name"],
    "excludes": ["name", "desc", "price"]
  },
  "query": {
    "match_all": {}
  }
}

Elasticsearch的_source字段在查詢時(shí)支持使用通配符(wildcards)來包含或排除特定字段。使得能夠更靈活地操縱返回的數(shù)據(jù)。

關(guān)于規(guī)則,可以參考以下幾點(diǎn):

  • *:匹配任意字符序列,包括空序列。
  • ?:匹配任意單個(gè)字符。
  • [abc]: 匹配方括號(hào)內(nèi)列出的任意單個(gè)字符。例如,[abc]將匹配"a", “b”, 或 “c”。

請(qǐng)注意,通配符表達(dá)式可能會(huì)導(dǎo)致查詢性能下降,特別是在大型索引中,因此應(yīng)謹(jǐn)慎使用。

全文檢索

全文檢索是Elasticsearch的核心功能之一,它可以高效地在大量文本數(shù)據(jù)中尋找特定關(guān)鍵詞。

在Elasticsearch中,全文檢索主要依靠?jī)蓚€(gè)步驟:“分析”(Analysis)和"查詢"(Search)。

  • 分析: 當(dāng)你向Elasticsearch插入一個(gè)文檔時(shí),會(huì)進(jìn)行"分析"處理,將原始文本數(shù)據(jù)轉(zhuǎn)換成稱為"tokens"或"terms"的小片段。這個(gè)過程可能包括如下操作:
    • 切分文本(Tokenization)
    • 將所有字符轉(zhuǎn)換為小寫(Lowercasing)
    • 刪除常見但無重要含義的單詞(Stopwords)
    • 提取詞根(Stemming)
  • 查詢:當(dāng)執(zhí)行全文搜索時(shí),查詢字符串也會(huì)經(jīng)過類似的分析過程,然后再與已經(jīng)分析過的數(shù)據(jù)進(jìn)行比對(duì),找出匹配的結(jié)果并返回。

Elasticsearch提供了許多種全文搜索的查詢類型,例如:

  • Match Query:最基本的全文搜索查詢。
  • Match Phrase Query:用于查找包含特定短語的文檔。
  • Multi-Match Query:類似Match Query,但可以在多個(gè)字段上進(jìn)行搜索。
  • Query String Query:提供了豐富的搜索語法,可以執(zhí)行復(fù)雜的、靈活的全文搜索。

match:匹配包含某個(gè)term的子句

match 查詢是 Elasticsearch 中的一種全文查詢方式,它包括標(biāo)準(zhǔn)分析和詞項(xiàng)搜索。盡管它可以應(yīng)用于精確字段,但其主要用途是進(jìn)行全文搜索。當(dāng)與全文字段一起使用時(shí),match 查詢可以解析查詢字符串,并執(zhí)行短語查詢或者構(gòu)建一個(gè)布爾查詢,這意味著它會(huì)考慮字段中的每個(gè)單詞。

下面有一個(gè)簡(jiǎn)單的 match 查詢示例:

GET /_search
{
  "query": {
    "match": {
      "message": "this is a test"
    }
  }
}

在這個(gè)示例中,Elasticsearch 會(huì)在 “message” 字段中搜索包含 “this”、“is”、“a” 和 “test” 的文檔。

請(qǐng)注意,match 查詢不僅僅會(huì)匹配完全相同的短語,它還可以處理更復(fù)雜的情況,如多個(gè)單詞(它會(huì)匹配任何一個(gè))、誤拼、同義詞等,這主要取決于你所使用的分析器和搜索設(shè)置。

match 查詢還有一些其他參數(shù),例如:

  • operator:定義多個(gè)搜索詞之間的關(guān)系,默認(rèn)為 or。如果設(shè)為 and,則返回的文檔必須包含所有搜索詞。
  • minimum_should_match:控制返回的文檔應(yīng)至少匹配的搜索詞的數(shù)量或比例。
  • fuzziness:允許模糊匹配,可以找到那些拼寫錯(cuò)誤或接近的詞匯。

match_all:匹配所有結(jié)果的子句

match_all是Elasticsearch中的一個(gè)查詢類型,用于獲取索引中的所有文檔。

這是一個(gè)match_all查詢的基本示例:

{
  "query": {
    "match_all": {}
  }
}

在上述示例中,我們可以看到查詢對(duì)象中存在一個(gè)"match_all"字段,其值是一個(gè)空對(duì)象。這表示我們希望匹配所有文檔。

需要注意,由于 match_all 查詢可能返回大量的數(shù)據(jù),所以一般在使用時(shí)都會(huì)與分頁(pagination)功能結(jié)合起來,這樣可以控制返回結(jié)果的數(shù)量,避免一次性加載過多數(shù)據(jù)導(dǎo)致的性能問題。例如,你可以使用 fromsize 參數(shù)來限制返回結(jié)果:

GET /_search
{
  "query": {
    "match_all": {}
  },
  "from": 10,
  "size": 10
}

Elasticsearch的 match_all 查詢是最簡(jiǎn)單的查詢,它不需要任何參數(shù),但如果你想為它添加權(quán)重,可以使用 boost 參數(shù)。例如:

GET /_search
{
    "query": {
        "match_all": { "boost" : 1.2 }
    }
}

在上面的查詢中,boost 參數(shù)被設(shè)置為1.2,給匹配到的所有文檔增加了額外的相關(guān)性得分提升。

multi_match:多字段條件

multi_match 可以用來在多個(gè)字段上進(jìn)行全文搜索。它接受一個(gè)查詢字符串和一組需要在其中執(zhí)行查詢的字段列表。

例如:

{
  "query": {
    "multi_match" : {
      "query":    "這是測(cè)試", 
      "fields": [ "field1", "field2" ] 
    }
  }
}

在此示例中,查詢字符串"這是測(cè)試"將在字段"field1"和"field2"中搜索。

multi_match查詢也支持使用通配符(*)來匹配多個(gè)字段:

{
  "query": {
    "multi_match" : {
      "query":    "這是測(cè)試", 
      "fields": [ "*_name" ] 
    }
  }
}

在這個(gè)例子中,會(huì)在所有以"_name"結(jié)尾的字段中進(jìn)行搜索。

此外,multi_match 查詢還支持許多參數(shù),包括:

  • type:設(shè)置查詢類型,可選值包括:best_fields, most_fields, cross_fields, phrase, phrase_prefix 等。

例如,“best_fields” 類型會(huì)從指定的字段中挑選分?jǐn)?shù)最高的匹配結(jié)果計(jì)算最終得分,而“most_fields” 類型則會(huì)在每個(gè)字段中都尋找匹配項(xiàng)并將其分?jǐn)?shù)累加起來。

  • tie_breaker:當(dāng)一個(gè)詞在多個(gè)字段中找到時(shí),用于決定最終得分的參數(shù)。
  • minimum_should_match:用于控制應(yīng)匹配的最小子句數(shù)。
  • operator:主要有兩個(gè)操作符 ORAND,默認(rèn)為 OR。

需要注意的是,當(dāng)使用 multi_match 查詢時(shí),如果字段不同,其權(quán)重可能也會(huì)不同。你可以通過在字段名后面添加尖括號(hào)(^)和權(quán)重值來調(diào)整特定字段的權(quán)重。例如,"fields": [ "name^3", "description" ]表示在"name"字段中的匹配結(jié)果權(quán)重是"description"字段的三倍。

match_phrase:短語查詢

match_phrase 用于精確匹配包含指定短語的文檔。match_phrase 查詢需要字段值中的單詞順序與查詢字符串中的單詞順序完全一致。

例如:

GET /_search
{
  "query": {
    "match_phrase": {
      "message": "this is a test"
    }
  }
}

這個(gè)查詢將會(huì)找到"message"字段中包含完整短語"this is a test"的所有文檔。

此外,match_phrase 查詢還有一個(gè) slop 參數(shù),可以定義詞組中的詞語可能存在的位置偏移量。例如,如果將 slop 設(shè)置為 1,則查詢 “this is a test” 也可匹配 “this is test a”,因?yàn)?“a” 和 “test” 只需移動(dòng)一個(gè)位置即可匹配。

GET /_search
{
  "query": {
    "match_phrase": {
        "query": "this is a test",
        "slop": 2
      }
  }
}

請(qǐng)注意,match_phrase 查詢需要整個(gè)短語完全匹配,而不僅僅是查詢中的所有單詞都存在。如果你只是希望所有單詞都存在,而不關(guān)心它們的順序或精確出現(xiàn)方式,那么你應(yīng)該使用 match 查詢。

Term Query

精確查詢用于查找包含指定精確值的文檔,而不是執(zhí)行全文搜索。

term:匹配和搜索詞項(xiàng)完全相等的結(jié)果

term 查詢主要用于查詢某個(gè)字段完全匹配給定值的文檔。這對(duì)精確匹配非常有效,例如數(shù)字、布爾值或者字符串。

用法示例:

GET /_search
{
    "query": {
        "term" : { "user" : "Kimchy" } 
    }
}

在這個(gè)例子中,我們正在搜索"user"字段中完全匹配"Kimchy"的文檔。

需要注意的是,term 查詢對(duì)于分析過的字段(例如,文本字段)可能不會(huì)像你預(yù)期的那樣工作,因?yàn)樗鼤?huì)搜索精確的詞匯項(xiàng),而不是單詞。如果你想要對(duì)文本字段進(jìn)行全文搜素,應(yīng)該使用 match 查詢。

另外一個(gè)需要注意的點(diǎn)就是 term 查詢對(duì)大小寫敏感,所以 “Kimchy” 和 “kimchy” 是兩個(gè)不同的詞條。

term和match_phrase的區(qū)別

term 查詢和 match_phrase 查詢是 Elasticsearch 提供的兩種查詢方式,它們都用于查找文檔,但主要的區(qū)別在于如何解析查詢字符串以及匹配的精確度。

  • term:這個(gè)查詢做的是精確匹配。當(dāng)你使用term查詢時(shí),Elasticsearch會(huì)查找完全等于你指定的詞匯的文檔。例如,如果你搜索term “apple”,那么只有包含完全為"apple"的文檔會(huì)被匹配到,而包含"apples"或"APPLE"的文檔則不會(huì)被匹配到。因此,term查詢對(duì)大小寫敏感,且不會(huì)進(jìn)行任何形式的分析(如停用詞移除、詞干提取等)。
  • match_phrase:這個(gè)查詢是用來匹配一系列詞匯或者短語的。match_phrase查詢會(huì)保證你查詢的詞匯必須以你提供的順序完全匹配。比如,如果你使用match_phrase查詢 “quick brown fox”,那么只有包含這個(gè)完整短語的文檔才會(huì)被匹配到,單獨(dú)包含"quick"、"brown"或者"fox"的文檔則不會(huì)被匹配到。此外,與term查詢不同,match_phrase查詢會(huì)進(jìn)行文本分析,這意味著它會(huì)考慮詞匯的大小寫、復(fù)數(shù)形式等。

總結(jié)來說,term查詢更適合精確匹配,而match_phrase查詢更適合短語匹配。但是,match_phrase并不能100%保證精確匹配,因?yàn)樗鼤?huì)處理和考慮文本的各種變體(比如,大小寫、單復(fù)數(shù)形式等)。

terms:匹配和搜索詞項(xiàng)列表中任意項(xiàng)匹配的結(jié)果

terms 查詢用于匹配指定字段中包含一個(gè)或多個(gè)值的文檔。這是一個(gè)精確匹配查詢,不會(huì)像全文查詢那樣對(duì)查詢字符串進(jìn)行分析。

假設(shè)你有一個(gè) “user” 的字段,并且你想找到該字段值為 “John” 或者 “Jane” 的所有文檔,你可以使用 terms 查詢:

GET /_search
{
  "query": {
    "terms" : {
      "user" : ["John", "Jane"],
      "boost" : 1.0
    }
  }
}

上面的查詢將返回所有"user" 字段等于 “John” 或者 “Jane” 的文檔。

其中boost 參數(shù)用于增加或減少特定查詢的相對(duì)權(quán)重。它將改變查詢結(jié)果的相關(guān)性分?jǐn)?shù)(_score),以影響最終結(jié)果的排名。

例如,在上述 terms 查詢中,boost 參數(shù)被設(shè)置為 1.0。這意味著如果字段 “user” 的值包含 “John” 或 “Jane”,那么其相關(guān)性分?jǐn)?shù)(_score)就會(huì)乘以 1.0。因此,這個(gè)設(shè)置實(shí)際上并沒有改變?nèi)魏螙|西,因?yàn)槌艘?1 不會(huì)改變?cè)挤謹(jǐn)?shù)。但是,如果你將 boost 參數(shù)設(shè)置為大于 1 的數(shù),那么匹配的文檔的 _score 將會(huì)提高,反之則會(huì)降低。

Range:范圍查找

Range查詢?cè)试S我們查找某個(gè)范圍內(nèi)的值。假設(shè)我們有一個(gè)商品表,其中有商品價(jià)格字段,我們可以用range查詢來查找價(jià)格在一定范圍內(nèi)的商品。

以下是一個(gè)基礎(chǔ)的范圍查詢的例子:

GET /products/_search
{
  "query": {
    "range" : {
        "price" : {
            "gte" : 10,
            "lte" : 20,
            "boost" : 2.0
        }
    }
  }
}

在這個(gè)例子中,我們正在查詢價(jià)格大于或等于(gte)10且小于或等于(lte)20的所有商品。"boost"參數(shù)表示增加該查詢的重要性。

Range查詢支持以下參數(shù):

  • gte:大于或等于。
  • lte:小于或等于。
  • gt:大于。
  • lt:小于。
  • boost:增加查詢的重要性。

此外,對(duì)于日期類型的字段,你還可以使用如下方式進(jìn)行范圍查詢:

{
  "query": {
    "range" : {
        "timestamp" : {
            "gte" : "now-1d/d",
            "lt" :  "now/d"
        }
    }
  }
}

在上述查詢中,我們正在查找過去24小時(shí)內(nèi)的數(shù)據(jù)。"now-1d/d"表示從現(xiàn)在算起的一天前,而"now/d"表示當(dāng)前時(shí)間。

Filter

過濾器(Filter)是用于篩選數(shù)據(jù)的一種工具。過濾器和查詢(query)相似,但有幾個(gè)重要的區(qū)別:

  • 過濾不關(guān)心文檔的相關(guān)度得分(relevance score):查詢會(huì)為每個(gè)匹配的文檔計(jì)算一個(gè)相關(guān)度得分,以決定返回結(jié)果的排序。相比之下,過濾器只關(guān)心文檔是否匹配 - 沒有“部分匹配”,只有“匹配”或“不匹配”。
  • 過濾器可以被緩存:由于過濾器不需要計(jì)算得分,因此它們的結(jié)果可以被緩存起來用于之后的搜索請(qǐng)求,這可以大大提高性能。

常見的過濾器類型包括:term、terms、range、boolmatch_all 等。例如,范圍過濾器 range 可以用于查找數(shù)字或日期字段在指定范圍內(nèi)的文檔;布爾過濾器 bool 則允許你組合多個(gè)過濾器,并定義它們?nèi)绾位ハ嘟换ァ?/p>

使用過濾器時(shí),通常會(huì)把它們放在 bool 查詢的 filter 子句中。例如:

{
  "query": {
    "bool": {
      "filter": [
        { "term":  { "status": "active" }},
        { "range": { "age": { "gte": 30, "lte": 40 }}}
      ]
    }
  }
}

這個(gè)查詢會(huì)返回所有“狀態(tài)為 active 并且年齡在 30 到 40 之間”的文檔,而不會(huì)考慮它們的相關(guān)度得分。

Filter緩存機(jī)制

在 Elasticsearch 中,過濾查詢結(jié)果的緩存機(jī)制是非常重要的一個(gè)性能優(yōu)化手段。由于過濾器(filter)只關(guān)心是否匹配,而不關(guān)心評(píng)分 (_score),因此它們的結(jié)果可以被緩存以提高性能。

每次 filter 查詢執(zhí)行時(shí),Elasticsearch 都會(huì)生成一個(gè)名為 “bitset” 的數(shù)據(jù)結(jié)構(gòu),其中每個(gè)文檔都對(duì)應(yīng)一個(gè)位(0 或 1),表示這個(gè)文檔是否與 filter 匹配。這個(gè) bitset 就是被存儲(chǔ)在緩存中的部分。

如果相同的 filter 查詢?cè)俅螆?zhí)行,Elasticsearch 可以直接從緩存中獲取這個(gè) bitset,而不需要再次遍歷所有的文檔來找出哪些文檔符合這個(gè) filter。這大大提高了查詢速度,并減少了 CPU 使用。

這種緩存策略特別適合那些重復(fù)查詢的場(chǎng)景,例如用戶界面的過濾器和類似的功能,因?yàn)樗麄兺ǔ?huì)產(chǎn)生很多相同的 filter 查詢。

然而,值得注意的是,雖然這種緩存可以顯著改善查詢性能,但也會(huì)占用內(nèi)存空間。如果你有很多唯一的過濾條件,那么過濾器緩存可能會(huì)變得很大,從而導(dǎo)致內(nèi)存問題。這就需要你對(duì)使用的過濾器進(jìn)行適當(dāng)?shù)墓芾砗拖拗啤?/p>

Filter緩存功能會(huì)遵循以下原則:

  • 同一Filter的多次應(yīng)用:如果在后續(xù)查詢中有多次使用相同的Filter,則ES會(huì)把第一次查詢的結(jié)果儲(chǔ)存在緩存中,后續(xù)的查詢將直接從緩存中獲取結(jié)果,而不再做任何磁盤I/O或者其他計(jì)算。
  • 根據(jù)需求清理緩存:ES會(huì)根據(jù)內(nèi)存使用情況自動(dòng)清理緩存,當(dāng)然你也可以手動(dòng)清空緩存。但這并不意味著我們無限制地依賴Filter緩存,大量的緩存可能導(dǎo)致更重的GC壓力。
  • 不緩存復(fù)雜查詢:一些查詢條件較復(fù)雜的過濾器可能不會(huì)被緩存,比如script filter、geo filter等。這是因?yàn)檫@些過濾器本身的構(gòu)建和維護(hù)成本可能就超過了查詢的計(jì)算成本。

ES的Filter緩存機(jī)制可以大大提高查詢效率,但如果不慎用,比如緩存過多或者不適合緩存的查詢,可能會(huì)對(duì)性能產(chǎn)生負(fù)面影響。因此,在設(shè)計(jì)和優(yōu)化ES查詢時(shí),應(yīng)當(dāng)充分考慮Filter的使用和緩存策略。

Bool Query

Bool Query(組合查詢)可以組合多個(gè)查詢條件,bool查詢也是采用more_matches_is_better的機(jī)制,因此滿足must和should子句的文檔將會(huì)合并起來計(jì)算分值。

一起學(xué)Elasticsearch系列-Query DSL,一起學(xué)Elasticsearch,elasticsearch,jenkins,大數(shù)據(jù)

boostminumum_should_match是參數(shù),其他四個(gè)都是查詢子句。

  • must:必須滿足子句(查詢)必須出現(xiàn)在匹配的文檔中,并將有助于得分。
  • filter:過濾器不計(jì)算相關(guān)度分?jǐn)?shù)。
  • should:滿足 or子句(查詢)應(yīng)出現(xiàn)在匹配的文檔中。
  • must_not:必須不滿足,不計(jì)算相關(guān)度分?jǐn)?shù) ,not子句(查詢)不得出現(xiàn)在匹配的文檔中。子句在過濾器上下文中執(zhí)行,這意味著計(jì)分被忽略,并且子句被視為用于緩存。

例子1:下面的語句表示:包含"xiaomi"或"phone" 并且包含"shouji"的文檔例子:

GET product/_search
{
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "name": "xiaomi phone"
                    }
                },
                {
                    "match_phrase": {
                        "desc": "shouji"
                    }
                }
            ]
        }
    }
}

should與must或filter一起使用

當(dāng) should 子句與 mustfilter 子句一起使用時(shí),這時(shí)候需要注意了。

只要滿足了 mustfilter 的條件,should 子句就不再是必須的。換句話說,如果存在一個(gè)或者多個(gè) mustfilter 子句,那么 should 子句的條件會(huì)被視為可選。

然而,如果 should 子句與 must_not 子句單獨(dú)使用(也就是沒有 mustfilter),則至少需要滿足一個(gè) should 子句的條件。

這里有一個(gè)例子來說明:

GET /_search
{
  "query": {
    "bool": {
      "must": [
        { "term": { "user": "kimchy" }}
      ],
      "filter": [
        { "term":  { "tag": "tech" }}
      ],
      "should": [
        { "term": { "tag": "wow" }},
        { "term": { "tag": "elasticsearch" }}
      ]
    }
  }
}

在這個(gè)查詢中,mustfilter 子句的條件是必須滿足的,而 should 子句的條件則是可選的。如果匹配的文檔同時(shí)滿足 should 子句的條件,那么它們的得分將會(huì)更高。

那如果我們一起使用的時(shí)候想讓should滿足該怎么辦?這時(shí)候minimum_should_match 參數(shù)就派上用場(chǎng)了。

minimum_should_match

minimum_should_match參數(shù)定義了在 should 子句中至少需要滿足多少條件。

例如,如果你有5個(gè) should 子句并且設(shè)置了 "minimum_should_match": 3,那么任何匹配至少三個(gè) should 子句的文檔都會(huì)被返回。

這個(gè)參數(shù)可以接收絕對(duì)數(shù)值(如 2)、百分比(如 30%)、和組合(如 3<90% 表示至少匹配3個(gè)或者90%,取其中較大的那個(gè))等不同類型的值。

注意:如果 bool 查詢中只有 should 子句(沒有 mustfilter),那么默認(rèn)情況下至少需要匹配一個(gè) should 條件,也就是minimum_should_match默認(rèn)值是1,除非 minimum_should_match 明確設(shè)定為其他值。如果包含 mustfilter的情況下minimum_should_match默認(rèn)值 0。

所以我們可以在包含mustfilter的情況下,設(shè)置minimum_should_match值來滿足should子句中的條件。文章來源地址http://www.zghlxwxcb.cn/news/detail-789319.html

到了這里,關(guān)于一起學(xué)Elasticsearch系列-Query DSL的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • ElasticSearch Index查詢(Query DSL)

    先貼一個(gè)Query DSL的官方文檔:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html 我平時(shí)喜歡查看官方文檔,了解數(shù)據(jù)查詢和存儲(chǔ)方面的性能優(yōu)化點(diǎn),下面是積累的腳本分享。 查詢語句格式 查詢類型:match_all,match,term,range,fuzzy,bool 等等 查詢條件:查詢條件會(huì)根

    2024年02月07日
    瀏覽(23)
  • ElasticSearch級(jí)查詢Query DSL上

    ElasticSearch級(jí)查詢Query DSL上

    目錄 ES高級(jí)查詢Query DSL match_all 返回源數(shù)據(jù)_source 返回指定條數(shù)size 分頁查詢fromsize 指定字段排序sort 術(shù)語級(jí)別查詢 Term query術(shù)語查詢 Terms Query多術(shù)語查詢 exists query ids query range query范圍查詢 prefix query前綴查詢 wildcard query通配符查詢 fuzzy query模糊查詢 ? ? ? ?ES中提供了一種強(qiáng)大

    2024年02月20日
    瀏覽(29)
  • ElasticSearch 高級(jí)查詢語法Query DSL實(shí)戰(zhàn)

    ElasticSearch 高級(jí)查詢語法Query DSL實(shí)戰(zhàn)

    ES中提供了一種強(qiáng)大的檢索數(shù)據(jù)方式,這種檢索方式稱之為Query DSL(Domain Specified Language 領(lǐng)域?qū)S谜Z言) , Query DSL是利用Rest API傳遞JSON格式的請(qǐng)求體(RequestBody)數(shù)據(jù)與ES進(jìn)行交互,這種方式的豐富查詢語法讓ES檢索變得更強(qiáng)大,更簡(jiǎn)潔。 官方文檔:https://www.elastic.co/guide/en/elasti

    2024年02月07日
    瀏覽(33)
  • elasticsearch 筆記二:搜索DSL 語法(搜索API、Query DSL)

    elasticsearch 筆記二:搜索DSL 語法(搜索API、Query DSL)

    從索引 tweet 里面搜索字段 user 為 kimchy 的記錄 從索引 tweet,user 里面搜索字段 user 為 kimchy 的記錄 從所有索引里面搜索字段 tag 為 wow 的記錄 說明:搜索的端點(diǎn)地址可以是多索引多 mapping type 的。搜索的參數(shù)可作為 URI 請(qǐng)求參數(shù)給出,也可用 request body 給出 URI 搜索方式通過 URI

    2024年02月04日
    瀏覽(18)
  • 2.ElasticSearch 高級(jí)查詢語法Query DSL實(shí)戰(zhàn)

    2.ElasticSearch 高級(jí)查詢語法Query DSL實(shí)戰(zhàn)

    ES中提供了一種強(qiáng)大的檢索數(shù)據(jù)方式,這種檢索方式稱之為Query DSL (Domain Specified Language 領(lǐng)域?qū)S谜Z言 ) , Query DSL是利用Rest API傳遞JSON格式的請(qǐng)求體(RequestBody)數(shù)據(jù)與ES進(jìn)行交互,這種方式的豐富查詢語法讓ES檢索變得更強(qiáng)大,更簡(jiǎn)潔。 Query DSL | Elasticsearch Guide [7.17] | Elastic 語法

    2024年03月15日
    瀏覽(33)
  • 【ES專題】ElasticSearch 高級(jí)查詢語法Query DSL實(shí)戰(zhàn)

    【ES專題】ElasticSearch 高級(jí)查詢語法Query DSL實(shí)戰(zhàn)

    個(gè)人在學(xué)習(xí)的過程中,感覺比較吃力的地方有如下: 語法結(jié)構(gòu)比較陌生 沒有中文文檔, 只能看英文 其他博客也比較少介紹語法結(jié)構(gòu)。比如說,為什么查詢中會(huì)出現(xiàn) query 有ES入門基礎(chǔ),且想進(jìn)一步學(xué)習(xí)ES基本操作的朋友 系列上一篇文章:《【ES專題】ElasticSearch快速入

    2024年02月06日
    瀏覽(25)
  • 【ElasticSearch-基礎(chǔ)篇】ES高級(jí)查詢Query DSL全文檢索

    和術(shù)語級(jí)別查詢(Term-Level Queries)不同,全文檢索查詢(Full Text Queries)旨在 基于相關(guān)性搜索和匹配文本數(shù)據(jù) 。這些查詢會(huì)對(duì)輸入的文本進(jìn)行分析,將其 拆分 為詞項(xiàng)(單個(gè)單詞),并執(zhí)行諸如分詞、詞干處理和標(biāo)準(zhǔn)化等操作。 全文檢索的關(guān)鍵特點(diǎn): 對(duì)輸入的文本進(jìn)行分析

    2024年01月22日
    瀏覽(11)
  • 15.Elasticsearch 7.15 Query DSL 之 Wildcard查詢、Regexp查詢

    返回包含與通配符模式匹配的文檔。 以下搜索返回 user.id 字段包含以 ki 開頭并以 y 結(jié)尾的文檔。這些匹配項(xiàng)可以包括 kiy、kity 或 kimchy (必填, 對(duì)象) 你想查詢的字段 參數(shù)名 描述 boost (Optional, float) 用于降低或提高查詢相關(guān)性得分的浮點(diǎn)數(shù)。默認(rèn)為1.0。 rewrite (可選,字符串)

    2023年04月08日
    瀏覽(36)
  • 【ElasticSearch-基礎(chǔ)篇】ES高級(jí)查詢Query DSL術(shù)語級(jí)別查詢并結(jié)合springboot使用

    Elasticsearch 提供了基于 JSON 的完整 Query DSL(Domain Specific Language)來定義查詢。 因Query DSL是利用Rest API傳遞JSON格式的請(qǐng)求體(RequestBody)數(shù)據(jù)與ES進(jìn)行交互,所以我們?cè)谑褂胹pringboot的時(shí)候也可以很方便的進(jìn)行集成,本文主要講述的就是使用springboot實(shí)現(xiàn)各類DSL的語法查詢。 Elastics

    2024年02月01日
    瀏覽(21)
  • Elasticsearch 系列(四)- DSL實(shí)現(xiàn)自動(dòng)補(bǔ)全查詢

    Elasticsearch 系列(四)- DSL實(shí)現(xiàn)自動(dòng)補(bǔ)全查詢

    本章將和大家分享如何通過 Elasticsearch 實(shí)現(xiàn)自動(dòng)補(bǔ)全查詢功能。 1、自動(dòng)補(bǔ)全需求說明 當(dāng)用戶在搜索框輸入字符時(shí),我們應(yīng)該提示出與該字符有關(guān)的搜索項(xiàng),如圖: 2、使用拼音分詞 要實(shí)現(xiàn)根據(jù)字母做補(bǔ)全,就必須對(duì)文檔按照拼音分詞。在 GitHub 上恰好有 Elasticsearch 的 拼音分

    2024年03月17日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包