全文搜索 (三) - match查詢和bool查詢的關係,提升查詢子句

轉自: http://blog.csdn.net/dm_vincent/article/details/41743955

match查詢是如何使用bool查詢的

現在,你也許意識到了使用了match查詢的多詞查詢只是簡單地將生成的term查詢包含在了一個bool查詢中。通過默認的or操作符,每個term查詢都以一個語句被添加,所以至少一個should語句需要被匹配。以下兩個查詢是等價的:

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

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

使用and操作符時,所有的term查詢都以must語句被添加,因此所有的查詢都需要匹配。以下兩個查詢是等價的:

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

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

如果指定了minimum_should_match參數,它會直接被傳入到bool查詢中,因此下面兩個查詢是等價的:

{
    "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 
  }
}

因爲只有3個查詢語句,minimum_should_match的值75%會被向下舍入到2。即至少兩個should語句需要匹配。

當然,我們可以通過match查詢來編寫這類查詢,但是理解match查詢的內部工作原理能夠讓你根據需要來控制該過程。有些行爲無法通過一個match查詢完成,比如對部分查詢詞條給予更多的權重。在下一節中我們會看到一個例子。



提升查詢子句(Boosting Query Clause)

當然,bool查詢並不是只能合併簡單的單詞(One-word)match查詢。它能夠合併任何其它的查詢,包括其它的bool查詢。它通常被用來通過合併數個單獨的查詢的分值來調優每份文檔的相關度_score

假設我們需要搜索和"full-text search"相關的文檔,但是我們想要給予那些提到了"Elasticsearch"或者"Lucene"的文檔更多權重。更多權重的意思是,對於提到了"Elasticsearch"或者"Lucene"的文檔,它們的相關度_score會更高,即它們會出現在結果列表的前面。

一個簡單的bool查詢能夠讓我們表達較爲複雜的邏輯:

GET /_search
{
    "query": {
        "bool": {
            "must": {
                "match": {
                    "content": { 
                        "query":    "full text search",
                        "operator": "and"
                    }
                }
            },
            "should": [ 
                { "match": { "content": "Elasticsearch" }},
                { "match": { "content": "Lucene"        }}
            ]
        }
    }
}
  1. content字段必須含有fulltextsearch這三個詞條
  2. 如果content字段也含有了詞條Elasticsearch或者Lucene,那麼該文檔會有一個較高的_score

should查詢子句的匹配數量越多,那麼文檔的相關度就越高。目前爲止還不錯。

但是如果我們想給含有Lucene的文檔多一些權重,同時給含有Elasticsearch的文檔更多一些權重呢?

我們可以通過指定一個boost值來控制每個查詢子句的相對權重,該值默認爲1。一個大於1boost會增加該查詢子句的相對權重。因此我們可以將上述查詢重寫如下:

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 
                    }
                }}
            ]
        }
    }
}

NOTE

boost參數被用來增加一個子句的相對權重(當boost大於1時),或者減小相對權重(當boost介於01時),但是增加或者減小不是線性的。換言之,boost設爲2並不會讓最終的_score加倍。

相反,新的_score會在適用了boost後被歸一化(Normalized)。每種查詢都有自己的歸一化算法(Normalization Algorithm),算法的細節超出了本書的討論範圍。但是能夠說一個高的boost值會產生一個高的_score

如果你在實現你自己的不基於TF/IDF的相關度分值模型並且你需要對提升過程擁有更多的控制,你可以使用function_score查詢,它不通過歸一化步驟對文檔的boost進行操作。

在下一章中,我們會介紹其它的用於合併查詢的方法,多字段查詢(Multifield Search)。但是,首先讓我們看看查詢的另一個重要特定:文本分析(Text Analysis)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章