ES 21 - Elasticsearch的高級檢索語法 (包括term、prefix、wildcard、fuzzy、boost等)

来源:https://www.cnblogs.com/shoufeng/archive/2019/06/28/11103913.html
-Advertisement-
Play Games

本篇博文簡單介紹Elasticsearch中term詞條檢索、prefix首碼檢索、wildcard通配符檢索、fuzzy糾錯檢索, 以及boost分數提升等高級檢索的用法, 最後通過複雜檢索的示例, 綜合演示這些檢索語法. ...


目錄

1 term query - 索引詞檢索

1.1 term query - 不分詞檢索

term query: 把檢索串當作一個整體來執行檢索, 即不會對檢索串分詞.

term是完全匹配檢索, 要用在不分詞的欄位上, 如果某個field在映射中被分詞了, term檢索將不起作用.
所以, 不分詞的field, 要在mapping中設置為不分詞.

—— ES 5.x之後, 為每個text類型的欄位新增了名為keyword的子欄位, 是不分詞的, 預設保留256個字元.

—— 可以使用keyword欄位進行term檢索. 示例:

GET shop/_search
{
    "query": {
        "term": {
            "name.keyword": "Java編程思想"
        }
    }
}

1.2 terms query - in檢索

terms, 相當於多個term檢索, 類似於SQL中in關鍵字的用法, 即在某些給定的數據中檢索:

GET shop/_search
{
    "query": {
        "terms": {
            "name.keyword": [
                "Java編程思想", "Java併發編程的藝術"
            ]
        }
    }
}

2 prefix query - 首碼檢索

prefix query, 就是首碼檢索. 比如商品name中有多個以"Java"開頭的document, 檢索首碼"Java"時就能檢索到所有以"Java"開頭的文檔.

—— 掃描所有倒排索引, 性能較差.

GET shop/_search
{
    "query": {
        "prefix": { "name": "java" }
    }
}

3 wildcard query - 通配符檢索

掃描所有倒排索引, 性能較差.

GET shop/_search
{
    "query": {
        "wildcard": { "name": "ja*" }
    }
}

4 regexp query - 正則檢索

掃描所有倒排索引, 性能較差.

GET shop/_search
{
    "query": {
        "regexp": { "name": "jav[a-z]*" }
    }
}

5 fuzzy query - 糾錯檢索

fuzziness的預設值是2 —— 表示最多可以糾錯兩次.

說明: fuzziness的值太大, 將削弱檢索條件的作用, 也就是說糾錯次數太多, 就會導致限定檢索結果的檢索條件被改變, 失去了限定作用.

示例: 檢索name中包含"Java"的文檔, Java中缺失了一個字母a:

GET shop/_search
{
    "query": {
        "match": { 
            "name": {
                "query": "Jav", 
                "fuzziness": 1, 
                "operator": "and"
            }
        }
    }
}

6 boost評分權重 - 控制文檔的優先順序別

通過boost參數, 令滿足某個條件的文檔的得分更高, 從而使得其排名更靠前.

GET shop/_search
{
    "query": {
        "bool": {
            "must": [
                { "match": { "name": "編程思想"} }
            ], 
            "should": [
                { 
                   "match": { 
                        "name": {
                            "query": "藝術", 
                            "boost": 2        // 提升評分權重
                        } 
                    }
                }
            ]
        }
    }
}

7 dis_max的用法 - best fields策略

一般檢索中, 檢索條件會被分詞, bool檢索構建多個子檢索 (must | must_not | should | filter), 這些子檢索可能會包含多個field. 這時:

多個子檢索的field各自匹配少量關鍵字的文檔的分數 > 某個子檢索的field匹配大量關鍵字的文檔的分數.

7.1 dis_max的提出

如果我們希望檢索結果中 (檢索串被分詞後的) 關鍵字匹配越多, 這樣的文檔就越靠前, 而不是多個子檢索中匹配少量分詞的文檔靠前.

⇒ 此時可以使用dis_max和tie_breaker.

tie_breaker的值介於0~1之間, Elasticsearch將 bool檢索的分數 * tie_breaker的結果與dis_max的最高分進行比較, 除了取dis_max的最高分以外, 還會考慮其他的檢索結果的分數.

7.2 使用示例

為了增加精準度, 常用的是配合boost、minimum_should_match等參數控制檢索結果.

GET shop/_search
{
    "query": {
        "dis_max": {
            "queries": [
                { "match": { "name": "虛擬機" } },
                { "match": { "desc": "經典" } }
            ],
            "tie_breaker": 0.2      // 對同時滿足的文檔的分值進行提升
        }
    }
}

GET shop/_search
{
    "query": {
        "dis_max": {
            "queries": [
                { 
                    "match": { 
                        "name": {
                            "query": "虛擬機",
                            "minimum_should_match": "50%",
                            "boost": 2
                        }
                    }
                },
                {
                    "match": {
                        "desc": {
                            "query": "經典",
                            "minimum_should_match": "50%", 
                            "boost": 3
                        }
                    }
                }
            ],
            "tie_breaker": 0.3
        }
    }
}

8 exist query - 存在檢索, 已過期

這是Elasticsearch 2.x中的API, 後續版本不再支持.

9 複雜檢索的使用範例

9.1 多條件過濾 - 包含

檢索出版時間在2012-07之後, 且至少滿足下述條件中一個的文檔:

a. 名稱(name)中包含"併發";

b. 描述(desc)中包含"java";

c. 出版社(publisher)名稱中不包含"電子".

GET shop/_search
{
    "query": {
        "bool": {
            "filter": {                 // 按時間過濾
                "range": {
                    "date": {"gte": "2012-07"}
                }
            },
            "should": [                 // 可匹配, 可不匹配
                {
                    "match": { "name": "併發" }
                },
                {
                    "bool": {
                        "must": {       // 必須匹配
                            "match": { "desc": "java" }
                        },
                        "must_not": {   // 不能匹配
                            "match": { "publisher": "電子" }
                        }
                    }
                }
            ],
            "minimum_should_match": 1   // 至少滿足should中的一個條件
        }
    }, 
    // 自定義排序
    "sort": [
        { "price": { "order": "desc" } }
    ]
}

註意: 排序的欄位最好是數字, 或日期, 因為字元串欄位會被分詞, ES會通過分詞後的某個詞去排序, 結果難以預測.

9.2 多條件拼接 - 包含+範圍+排序

匹配檢索: name中包含"java"卻不包含"虛擬機";
範圍檢索: 價格大於50、小於80;
結果排序: 按照價格升序排序.

GET shop/_search
{
    "query": {
        "bool": {
            "must": {                       // 必須匹配
                "match": { "name": "java" }
            }, 
            "must_not": {                   // 必須不匹配
                "match": { "name": "虛擬機" }
            },
            "filter": {
                "range": {
                    "price": {
                        "gte": 40,
                        "lte": 80,
                        "boost": 2.0    // 設置得分的權重值(提升值), 預設是1.0
                    }
                }
            }
        }
    }
}

關於範圍檢索的使用, 請參考下篇文章: ES 22 - Elasticsearch對數值或日期類型進行範圍檢索

9.3 定製檢索結果的排序規則

(1) 預設排序規則:

ES預設是按檢索結果的分值(_score)降序排列的.

某些情況下, 可能存在無實際意義的_score, 比如filter時所有_score的值都相同:

GET website/_search
{
    "query": {
        "bool": {
            "filter": {
                "term": {
                    "author_id": 5520   // 此時所有符合條件的_score都為0
                }
            }
        }
    }
}

// 或通過constant_score過濾: 
GET website/_search
{
    "query": {
        "constant_score": {
            "filter": {
                "term": {
                    "author_id": 5520   // 此時所有符合條件的_score都為1
                }
            }
        }
    }
}

(2) 定製排序規則:

GET website/_search
{
    "query": {
        "constant_score": {
            "filter": {
                "term": {
                    "author_id": 5520
                }
            }
        }
    }, 
    "sort": [
        {
            "post_date": { "order": "asc" }
        }
    ]
}

版權聲明

作者: 馬瘦風(https://healchow.com)

出處: 博客園 馬瘦風的博客(https://www.cnblogs.com/shoufeng)

感謝閱讀, 如果文章有幫助或啟發到你, 點個[

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • [博客園TinyMCE編輯器]利用鏈接和書簽功能實現頁內跳轉 1.選中需要跳轉的文字,如我需要點擊A然後跳轉到B,那麼就先選中文字B,然後點擊工具欄的錨狀圖標,輸入書簽名字。書簽名字可以是字母或數字,但必須是字母開頭。 2.選中文字B,插入鏈接,在彈出的視窗中,錨點選擇“mark1”,目標選擇“在目 ...
  • 字元串 可以使用單引號和雙引號定義字元串變數但是單引號中不支持變數解析 獲取字元串的長度 截取字元串 查找指定字元 數組 獲取數組長度 ...
  • 設置帶有密碼和訪問許可權的共用文件夾 目錄導航: 1.啟用網路發現和密碼訪問共用 2.設置用於訪問共用文件夾的用戶和密碼 3.創建共用文件夾並設置訪問許可權 4.訪問共用的文件夾 1. 啟用網路發現和密碼訪問共用 返回目錄導航 1.1 使用組合鍵“Win+R”打開運行視窗,輸入“control”打開控制 ...
  • 我們公司2019年web開發已遷移至.NET core,目前有部分平臺隨著用戶量增加,單一資料庫部署已經無法滿足我們的業務需求,一直在尋找EF CORE讀寫分離解決方案,目前在各大技術論壇上還沒找到很好的方案,根據之前找到的讀寫分離方案,綜合目前EF core 的能力,自己編寫了一套EF core實 ...
  • MongoDB和關係型資料庫的對應關係 關係資料庫示例: MongoDB對應的: 資料庫(database) 一個MongoDB中可以建立多個資料庫,這些資料庫是相互獨立的,有自己的集合和許可權。不同的資料庫使用不同的文件存儲(不存儲在一個文件中)。 MongoDB預設有4個資料庫: admin: 從 ...
  • 簡述 博主最近因工作任務纏身,都無暇顧及到我的這片自留地了。前段時間稍有空閑,花了較多的精力學習《啊哈演算法》,從中學習到很多之前沒有太註重的內容,收益頗豐。但是這些演算法題目還沒有看完,等後面有時間了,還需重新自我溫習一下前面所寫的內容,並且繼續耕耘後面的演算法知識。 今天稍微有點時間,總結一下博主近期 ...
  • 資料庫概念 資料庫(Database)是按照數據結構來組織、存儲和管理數據的建立在電腦存儲設備上的倉庫。 資料庫:存儲數據的倉庫 資料庫分類 網路資料庫 網路資料庫是指把資料庫技術引入到電腦網路系統中,藉助於網路技術將存儲於資料庫中的大量信息及時發佈出去;而電腦網路藉助於成熟的資料庫技術對網路 ...
  • 伺服器配置文件分析 bin目錄下的mongod.cfg是伺服器的配置文件,文件中主要的配置參數: 1、資料庫文件的存放位置 2、伺服器日誌文件的存放位置 3、預設的IP地址、埠號 設置密碼 預設情況下,MongoDB的伺服器地址是127.0.0.1,埠號是27017,存儲資料庫管理員信息的adm ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...