1. 程式人生 > >elasticsearch筆記_全文搜尋_query(五)

elasticsearch筆記_全文搜尋_query(五)

全文搜尋(Query)

全文搜尋最重要的兩個方面就是”相關性(Relevance)”和”分析(Analysis)” .

相關性(Relevance)

每個文件都有相關性評分,用一個正浮點數字段 _score 來表示 。_score 評分越高 , 相關性就越高 。

檢索詞頻率TF(Token Frequency):檢索詞出現的頻率,出現頻率越多,相關性越高.(例如:檢索詞出現5次比出現1次的的相關性要高.)

反向文件頻率IDF(Inverse Document Frequency):每個詞在索引(名詞)中出現的頻率,頻率越高,相關性越低。檢索詞出現在多數文件中會比出現在少數文件中的權重更低。

欄位長度準則:欄位的長度.長度越長,相關性越低。檢索詞出現在一個短的 title 要比同樣的詞出現在一個長的 content 欄位權重更大。

注意 : 相關性的概念並不只用於全文搜尋,也適用於 yes|no 的子句,匹配的子句越多,相關性評分越高。

關於TF/IDF的解釋:

有很多不同的數學公式可以用來計算TF-IDF。這邊的例子以上述的數學公式來計算。詞頻 (TF) 是一詞語出現的次數除以該檔案的總詞語數。假如一篇檔案的總詞語數是100個,而詞語“母牛”出現了3次,那麼“母牛”一詞在該檔案中的詞頻就是3/100=0.03。一個計算檔案頻率 (IDF) 的方法是測定有多少份檔案出現過“母牛”一詞,然後除以檔案集裡包含的檔案總數。所以,如果“母牛”一詞在1,000份檔案出現過,而檔案總數是10,000,000份的話,其逆向檔案頻率就是 log(10,000,000 / 1,000)=4。最後的TF-IDF的分數為0.03 * 4=0.12。

主要是為了去掉無用詞條,例如漢語裡面的”的”,”是”等無用詞.

分析(Analysis)

match查詢(單個詞搜尋)

match查詢最強大 , 既能處理全文欄位 , 又能處理精確欄位 .

1 : 搜尋關鍵字是一個單個字.

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

查詢步驟 :
1.檢查欄位型別 : 標題 title 欄位是一個 string 型別( analyzed )已分析的全文欄位,這意味著查詢字串本身也應該被分析。

2.分析查詢字串 : 將查詢的字串 QUICK! 傳入標準分析器中,輸出的結果是單個項 quick 。因為只有一個單詞項,所以 match 查詢執行的是單個底層 term 查詢。

3.查詢匹配文件 :用 term 查詢在倒排索引中查詢 quick 然後獲取一組包含該項的文件.

4.為每個文件評分 (根據相關性的判斷)。

match搜尋(多詞搜尋)

2:搜尋關鍵字是一組單詞.

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

查詢步驟 : 將多個關鍵字進行拆分 , 它在內部實際上先執行兩次 term 查詢,然後將兩次查詢的結果合併作為最終結果輸出。為了做到這點,它將兩個 term 查詢包入一個 bool 查詢中.

精確度控制

在上面的搜尋裡面,只要包含兩個關鍵字的任意一個的文件就被認為是符合要求的 . 換句話說匹配的是 brown OR dog ,如果希望匹配 brown AND dog 去檢索文件,可以控制match裡面的operator引數 .

GET /my_index/my_type/_search
{
    "query": {
        "match": {
            "title": {      
                "query":    "BROWN DOG!",
                "operator": "and"
            }
        }
    }
}

如果關鍵詞是4個,想要匹配3個,這種情況可以使用minimum_should_match引數,配置引數為75%:

GET /my_index/my_type/_search
{
  "query": {
    "match": {
      "title": {
        "query":                "quick brown dog",
        "minimum_should_match": "75%"
      }
    }
  }
}

如果關鍵字是3個,還寫了75%,會被預設為66.6%.

組合查詢(bool查詢)的評分標準和精確度控制

評分標準 :

bool過濾的must 、 must_not 和 should在bool查詢這裡一樣可以用,不過bool查詢除了決定一個文件是否應該被包括在結果中,還會計算文件的 相關程度 。

GET /my_index/my_type/_search
{
  "query": {
    "bool": {
      "must":     { "match": { "title": "quick" }},
      "must_not": { "match": { "title": "lazy"  }},
      "should": [
                  { "match": { "title": "brown" }},
                  { "match": { "title": "dog"   }}
      ]
    }
  }
}

bool 查詢會為每個文件計算相關度評分 _score , 再將所有匹配的 must 和 should 語句的分數 _score 求和,最後除以 must 和 should 語句的總數。must_not 語句不會影響評分; 它的作用只是將不相關的文件排除。

精確度控制 : 與match 查詢的精度控制一樣,我們可以通過 minimum_should_match 引數控制需要匹配的 should 語句的數量, 它既可以是一個絕對的數字,又可以是個百分比

GET /my_index/my_type/_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "title": "brown" }},
        { "match": { "title": "fox"   }},
        { "match": { "title": "dog"   }}
      ],
      "minimum_should_match": 2  //得有兩個should滿足條件才算匹配.
    }
  }
}

注意 : 其實多詞 match 查詢只是簡單地將生成的 term 查詢包裹 在一個 bool 查詢中。如果使用預設的 or 操作符,每個 term 查詢都被當作 should 語句,這樣就要求必須至少匹配一條語句。

以下兩個是等價的:

{
    "match": { "title": "brown fox"}
}

{
 "bool": {
    "should": [
      { "term": { "title": "brown" }},
      { "term": { "title": "fox"   }}
    ]
  }
}

以下兩個是等價的:

{
    "match": {
        "title": {
            "query":    "brown fox",
            "operator": "and"
        }
    }
}

{
  "bool": {
    "must": [
      { "term": { "title": "brown" }},
      { "term": { "title": "fox"   }}
    ]
  }
}

以下兩個是等價的:

{
    "match": {
        "title": {
            "query":                "quick brown fox",
            "minimum_should_match": "75%"
        }
    }
}

{
  "bool": {
    "should": [
      { "term": { "title": "brown" }},
      { "term": { "title": "fox"   }},
      { "term": { "title": "quick" }}
    ],
    "minimum_should_match": 2 
  }
}

權重的提升

可以通過指定 boost 來控制任何查詢語句的相對的權重,boost 的預設值為 1 ,大於 1 會提升一個語句的相對權重。舉例 :

GET /_search
{
    "query": {
        "bool": {
            "must": {
                "match": {  
                    "content": {
                        "query":    "full text search",
                        "operator": "and"
                    }
                }
            },
            "should": [
                { "match": {
                    "content": {
                        "query": "Elasticsearch",
                        "boost": 3 
                    }
                }},
                { "match": {
                    "content": {
                        "query": "Lucene",
                        "boost": 2 
                    }
                }}
            ]
        }
    }
}

上面的例子裡面 must語句預設使用的boost值是1 , 關鍵字 Lucene的boost值設為2 , 使Lucene變得更重要 . Elasticsearch的boost值設為3 ,說明它比Lucene更重要 . 更高的 boost 值為我們帶來更高的評分 _score .

注意:boost的值並不一定是線性的,意思就是boost的值設定為2不一定就是boost值為1的兩倍 .

關於分析器的說明:

1 . match 查詢為每個欄位使用合適的分析器,以保證它在尋找每個項時都為該欄位使用正確的格式。

2 . 分析器可以從三個層面進行定義:按欄位(per-field)、按索引(per-index)或全域性預設(global default)。

3 . Elasticsearch在索引(動詞)時會按照以下順序依次找到能夠使用的分析器 :
(1) 欄位對映裡定義的 analyzer .
(2) 索引設定中名為 default 的分析器.
(3) standard 標準分析器.

4 . Elasticsearch在搜尋時會按照以下順序依次找到能夠使用的分析器 :
(1) 查詢自己定義的 analyzer ,否則
(2) 欄位對映裡定義的 search_analyzer ,否則
(3) 欄位對映裡定義的 analyzer ,否則
(4) 索引設定中名為 default_search 的分析器,預設為
(5) 索引設定中名為 default 的分析器,預設為
(6) standard 標準分析器