Full Text Search

全文搜索

1、相關(guān)性
評價(jià)查詢與其結(jié)果間的相關(guān)程度,并根據(jù)這種相關(guān)程度對結(jié)果排名。
計(jì)算方式:TF/IDF、地理位置鄰近、模糊相似、或者其他某些算法。
2、分析
將文本轉(zhuǎn)換為有區(qū)別的、規(guī)范化的token的一個(gè)過程。
創(chuàng)建倒排索引以及查詢倒排索引

基于詞項(xiàng)與基于全文

1、基于詞項(xiàng)的查詢
term或fuzzy這樣的底層查詢不需要分析階段,它們對單個(gè)詞項(xiàng)進(jìn)行操作。
只需要在倒排索引中查找準(zhǔn)確詞項(xiàng)。
2、基于全文的查詢
match或query_string這樣的查詢是高層查詢,它們了解字段映射的信息:
-如果查詢date或integer字段,它們會將查詢字符串分別作為date或integer對待。
-如果查詢not_analyzed的精確值字符串字段,它們會將整個(gè)查詢字符串作為單個(gè)詞項(xiàng)對待。
-如果查詢analyzed的全文字段,它們會先將查詢字符串傳遞到一個(gè)合適的分析器,然后生成一個(gè)供查詢的詞項(xiàng)列表。
一旦組成了詞項(xiàng)列表,這個(gè)查詢會對每個(gè)詞項(xiàng)逐一執(zhí)行底層的查詢。

匹配查詢

match是個(gè)核心查詢、高級全文查詢,既能處理全文字段,又能處理精確字段。
它是首選的查詢方式
單個(gè)詞查詢

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

es執(zhí)行上面這個(gè)match查詢的步驟是:
1、檢查字段類型。
title字段是一個(gè)string類型的全文字段,意味著查詢字符串本身也應(yīng)該被分析。
2、分析查詢字符串。
傳入標(biāo)準(zhǔn)分析中,輸出的結(jié)果是單個(gè)項(xiàng)quick。因?yàn)槭且粋€(gè)單詞項(xiàng),所以match查詢執(zhí)行的單個(gè)底層term查詢
3、查詢匹配文檔
4、為每個(gè)文檔評分

多詞查詢

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

與單詞項(xiàng)查詢類似,只不過term會被執(zhí)行多次(多個(gè)term包入一個(gè)bool中)
多詞查詢默認(rèn)情況下,只要匹配一個(gè)詞就會被匹配(or)

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

使用operator可以修改成and,多個(gè)詞都被匹配,文檔才會被匹配
還可以使用"minimum_should_match": "75%"75%的詞項(xiàng)被匹配,文檔就會被匹配
但是假如只有三個(gè)詞項(xiàng),75%會被自動(dòng)階段成66.6%

組合查詢

在組合過濾器中,使用bool進(jìn)行組合,在查詢中bool也有類似的功能,只有一個(gè)重要的區(qū)別。
過濾器是非黑即白的,然而查詢會計(jì)算文檔的相關(guān)程度。

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

上述查詢must和must_not與bool過濾器的工作方式非常相似。
區(qū)別在于兩個(gè)should語句:不必包含,但是包含了就更相關(guān)了
bool查詢會為每個(gè)文檔計(jì)算相關(guān)度評分_score,再將所有匹配的must和should語句的分?jǐn)?shù)_score求和,最后除以must和should語句的總數(shù)。
must_not不影響評分,只是將不相關(guān)的文檔排除。
默認(rèn)情況下沒有should語句是必須匹配的,但是當(dāng)沒有must語句的時(shí)候。至少有一個(gè)should語句必須匹配
類似控制match查詢的精度一樣,minimum_should_match也可以控制should語句的精度,可以是數(shù)字,也可以是百分比

GET /my_index/my_type/_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "title": "brown" }},
        { "match": { "title": "fox"   }},
        { "match": { "title": "dog"   }}
      ],
      "minimum_should_match": 2
    }
  }
}

查詢語句提升權(quán)重

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

這個(gè)查詢中content字段必須包含full/text/search,如果包含 Elasticsearch/Lucene會獲得更高的評分。
我們想要Elasticsearch/Lucene的權(quán)重有些變化,可以使用boost(默認(rèn)值是1,取值范圍>0),boost的提升或者降低不是線性的。有一個(gè)歸一化的過程

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

控制分析

可以為字段指定分析器,也可以使用type/index/node的默認(rèn)配置
可以使用analyze API來分析單詞

GET /my_index/_analyze
{
  "field": "my_type.title",   (1)
  "text": "Foxes"
}

GET /my_index/_analyze
{
  "field": "my_type.english_title",   (2)
  "text": "Foxes"
}

1使用默認(rèn)的standard標(biāo)準(zhǔn)分析器,返回詞項(xiàng)foxes
2使用english英語分析器,返回詞項(xiàng)fox
意味著使用term查詢精確項(xiàng)fox時(shí),english_title字段會匹配,但title字段不會
可以使用validate-query API來查看高層查詢(例如match)的分析行為

GET /my_index/my_type/_validate/query?explain
{
    "query": {
        "bool": {
            "should": [
                { "match": { "title":         "Foxes"}},
                { "match": { "english_title": "Foxes"}}
            ]
        }
    }
}

返回語句的explanation結(jié)果:

(title:foxes english_title:fox)

默認(rèn)分析器

按照層級順序查找分析器,直到找到能夠使用的分析器。
索引時(shí)的順序如下
1、字段映射里定義的analyzer
2、索引設(shè)置中名為default的分析器,默認(rèn)為standard
3、standard標(biāo)準(zhǔn)分析器
查詢時(shí)的順序如下:
1、查詢自己定義的analyzer
2、字段映射里定義的analyzer
3、索引設(shè)置中名為default的分析器,默認(rèn)為standard
4、standard標(biāo)準(zhǔn)分析器
索引時(shí)和搜索時(shí)使用不同的分析器是合理,例如為同義詞建索引,但在搜索時(shí)我們不需要搜索所有同義詞。
為了區(qū)分,es支持一個(gè)可選的search_analyzer映射,以及一個(gè)等價(jià)的default_search映射
搜索時(shí),完整順序如下:
1、查詢自己定義的analyzer
2、字段映射里定義的search_analyzer
3、字段映射里定義的analyzer
4、索引設(shè)置中名為default_search的分析器,默認(rèn)為standard
5、索引設(shè)置中名為default的分析器,默認(rèn)為standard
6、standard標(biāo)準(zhǔn)分析器

被破壞的相關(guān)度?。?!

用戶索引了一些文檔,運(yùn)行一個(gè)簡單的查詢,然后發(fā)現(xiàn)明顯低相關(guān)度的結(jié)果出現(xiàn)在高相關(guān)度結(jié)果之上。
由于相似度算法TF/IDF,詞頻/逆向文檔頻率
詞頻是某個(gè)詞在“當(dāng)前被查詢文檔”里面某個(gè)字段中出現(xiàn)的頻率
逆向文檔頻率是將某個(gè)詞在索引內(nèi)“所有文檔”出現(xiàn)的百分?jǐn)?shù)
需要注意的是,es不會計(jì)算索引內(nèi)所有文檔的IDF,只會計(jì)算分片的本地IDF。
數(shù)據(jù)較少時(shí),不同分片的IDF差異較大,就會導(dǎo)致相關(guān)度被破壞
可以在搜索請求后添加?search_type=dfs_query_then_fetch,dfs 是指 分布式頻率搜索(Distributed Frequency Search)分別獲得每個(gè)分片本地的IDF,然后根據(jù)結(jié)果再計(jì)算全局IDF
實(shí)際上!完全沒有必要使用,只要有足夠的數(shù)據(jù)就能保證詞頻是均勻分布的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容