ES全文檢索基本招式

一、match

  1. 在執行match查詢時,默認情況下,字段值必須匹配任意一個詞條,比如文檔的eventname字段匹配任意一個分詞,azure、aws和cloud時,該文檔就匹配
POST /_search -d
{  
   "from":10,
   "size":5,
   "query":{  
      "match":{  
         "eventname":"azure aws cloud"
      }
   }
}
  1. 匹配分詞的數量是由匹配參數控制的,match查詢常用的參數:
  • operator:用來控制match查詢匹配詞條的邏輯條件,默認值是or,如果設置為and,表示查詢滿足所有條件;
  • minimum_should_match:當operator參數設置為or時,該參數用來控制應該匹配的分詞的最少數量;Elastic控制查詢精準度-minimum_should_match
POST /search -d{  
   "from":10,
   "size":5,
   "query":{  
      "match":{  
         "eventname":{  
            "query":"azure aws cloud security",
            "operator":"or",
            "minimum_should_match":2
         }
      }
   }
}
POST /search -d{  
   "from":10,
   "size":5,
   "query":{  
      "match":{  
         "eventname":{  
            "query":"azure aws cloud security",
            "operator":"adn"
         }
      }
   }
}
  1. 底層實現的轉換 將multi-query 轉換為 bool+ must/should + term
    3.1、or
    GET /forum/article/_search
{
    "query": {
        "match": {
            "title": "java elasticsearch"
        }
    }
}

相當于:bool should term

{
  "bool": {
    "should": [
      { "term": { "title": "java" }},
      { "term": { "title": "elasticsearch"   }}
    ]
  }
}

3.2、and
如果title字段是analyzed則進行full text全文搜索,則返回title字段包含java 或者elasticsearch 或者兩個都包含的document
如果是not_analyzed則進行exact value(相當于temr query),則只返回包含java elasticsearch的document

GET /forum/article/_search
{
    "query": {
        "match": {
            "title": {
        "query": "java elasticsearch",
        "operator": "and"              //full text 中 返回都包含“java”和"elasticsearch“的document
           }
        }
    }
}

相當于:bool must term

   {
      "bool": {
     "must": [
      { "term": { "title": "java" }},
      { "term": { "title": "elasticsearch"   }}
        ]
      }
    }

3.3、minimum_should_match

GET /forum/article/_search
{
  "query": {
    "match": {
      "title": {
        "query": "java elasticsearch spark hadoop",
        "minimum_should_match": "75%"  // full text中返回,包含指定條件的75%的document
      }
    }
  }
}

相當于:bool should term minimum_should_match

{
  "bool": {
    "should": [
      { "term": { "title": "java" }},
      { "term": { "title": "elasticsearch"   }},
      { "term": { "title": "hadoop" }},
      { "term": { "title": "spark" }}
    ],
    "minimum_should_match": 3
  }
}

補充知識點:must和should對分數有影響;must是必須條件,之后should匹配的越多則分數越高
更多參考:布爾匹配查詢

二、短語匹配查詢(match_phrase)

Elasticsearch - 短語匹配(match_phrase)以及slop參數

在執行短語匹配查詢時,ElasticSearch引擎首先分析(analyze)查詢字符串,從分析后的文本中構建短語查詢:

  • 必須匹配短語中的所有分詞
  • 保證各個分詞的相對位置不變
POST /_search -d
{  
   "from":1,
   "size":100,
   "fields":[ "eventname"],
   "query":{  
      "match_phrase":{  
         "eventname":"Open Source"
      }
   }
}

"this is an Open Souce xxx" 匹配
“Open this Source code xxx" 不匹配

短語匹配使用slop參數來引入一些靈活性;slop參數告訴match_phrase查詢詞條能夠相隔多遠時仍然將文檔視為匹配;其中移動可以是反向的,比如這樣的場景:Open 左移,Source 又移

GET /my_index/my_type/_search
{
    "query": {
        "match_phrase": {
            "title": {
                "query": "Open Source",
                "slop":  2
            }
        }
    }
}

三、 boost條件權重控制

默認情況下,搜索條件的權重都是一樣的,都是1;boost控制搜索條件的權重,可以將某個搜索條件的權重加大,此時當匹配這個搜索條件和匹配另一個搜索條件的document,計算relevance score時,匹配權重更大的搜索條件的document,relevance score會更高,也就會優先被返回。

GET /forum/article/_search 
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": "blog"
          }
        }
      ],
      "should": [
        {
          "match": {
            "title": {
              "query": "elasticsearch"
            }
          }
        },
        {
          "match": {
            "title": {
              "query": "spark",
              "boost": 5
            }
          }
        }
      ]
    }
  }
}

四、most fields評分算法

GET /forum/article/_search
{
    "query": {
        "bool": {
            "should": [
                { "match": { "title": "java solution" }},
                { "match": { "content":  "java solution" }}
            ]
        }
    }
}

按照多個字段的綜合匹配情況來計算整體分值,不會因為某個字段的匹配對最高而干擾最終結果,這點是與best fields的區別。
計算每個document的relevance score:每個query的分數之和,乘以matched query數量,除以總query數量,比如:總共2個match :

  1. doc4的情況是這樣:
    doc4 跟match1 部分匹配,有一個"java" 分值1.1
    doc4 跟match2 部分匹配,有一個"solution" 分值1.2
    每個query的分數之和:1.1 + 1.2 = 2.3
    matched query數量 : 2
    總query數量 :2
    2.3 * 2 / 2 = 2.3
  2. doc5的情況是這樣
    doc5 跟match1不匹配,沒有分值
    doc5 跟match2匹配,匹配度很高,有 "java solution" 分值為2.3
    每個query的分數之和:2.3
    matched query數量 :1
    總query數量 : 2
    2.3 * 1 / 2 = 1.15

doc5的分數 = 1.15 < doc4的分數 = 2.3

還有一些內容暫未記錄, Elasticsearch頂尖高手系列課程之高手進階篇

五、best fields策略

搜索到的結果,應該是某一個field中匹配到了盡可能多的關鍵詞,被排在前面;而不是盡可能多的field匹配到了少數的關鍵詞,排在了前面

dis_max語法,直接取多個query中,分數最高的那一個query的分數,完全不考慮其他字段的分數

GET /forum/article/_search
{
    "query": {
        "dis_max": {
            "queries": [
                { "match": { "title": "java solution" }},
                { "match": { "content":  "java solution" }}
            ]
        }
    }
}
1.使用tie_breaker 優化 dis_max

使用tie_breaker將其他query的分數也考慮進去

tie_breaker參數的意義,在于說,將其他query的分數,乘以tie_breaker,然后綜合與最高分數的那個query的分數,綜合在一起進行計算
除了取最高分以外,還會考慮其他的query的分數
tie_breaker的值,在0~1之間,是個小數,就ok

GET /forum/article/_search
{
    "query": {
        "dis_max": {
            "queries": [
                { "match": { "title": "java beginner" }},
                { "match": { "body":  "java beginner" }}
            ],
            "tie_breaker": 0.3
        }
    }
}

更多參考: Elasticsearch頂尖高手系列課程之高手進階篇

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。