Multi_field_Search

多字符串查詢

GET /_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "title":  "War and Peace" }},
        { "match": { "author": "Leo Tolstoy"   }},
        { "bool":  {
          "should": [
            { "match": { "translator": "Constance Garnett" }},
            { "match": { "translator": "Louise Maude"      }}
          ]
        }}
      ]
    }
  }
}

4個(gè)match查詢郭蕉,為什么后兩個(gè)使用bool包裹冕象?
同一層查詢每條語(yǔ)句具有相同的權(quán)重\堋F竞馈焙蹭!

語(yǔ)句的優(yōu)先級(jí)

boost

單字符串查詢

用戶期望將所有的搜索項(xiàng)堆積到單個(gè)字段中。
1嫂伞、最佳字段
例如我們搜索“es reindex”孔厉,對(duì)于title和body這樣的兩個(gè)字段拯钻,“es reindex”同時(shí)出現(xiàn)在一個(gè)字段時(shí)的文檔評(píng)分更高
2、多數(shù)字段
為了對(duì)相關(guān)度進(jìn)行微調(diào)烟馅,常用的一個(gè)技術(shù)就是將相同的數(shù)據(jù)索引到不同的字段说庭,使他們具有獨(dú)立的分析鏈。
主字段可能包括它們的詞源郑趁、同義詞以及變音詞或口音詞等刊驴,用來(lái)匹配盡可能多的文檔。
相同的文本被索引到其他字段寡润,提供更精確的匹配捆憎。一個(gè)字段可以包括未經(jīng)詞干提取的原詞;另一個(gè)字段包括口音梭纹,還有一個(gè)字段提供詞語(yǔ)相似性躲惰。
其他字段是作為匹配每個(gè)文檔時(shí)提高相關(guān)度評(píng)分的信號(hào)。
3变抽、混合字段
對(duì)于某些實(shí)體础拨,需要在多個(gè)字段中確認(rèn)其信息,單個(gè)字段都只能作為整體的一部分:
Person: first_name绍载、last_name
如同在Persion這個(gè)大字段中搜索 first_name和last_name這兩個(gè)字段

最佳字段

以兩個(gè)文檔為例

PUT /my_index/my_type/1
{
    "title": "Quick brown rabbits",
    "body":  "Brown rabbits are commonly seen."
}

PUT /my_index/my_type/2
{
    "title": "Keeping pets healthy",
    "body":  "My quick brown fox eats rabbits on a regular basis."
}

bool查詢诡宗,想要匹配Brown fox

{
    "query": {
        "bool": {
            "should": [
                { "match": { "title": "Brown fox" }},
                { "match": { "body":  "Brown fox" }}
            ]
        }
    }
}

我們想要的結(jié)果是文檔2,但是文檔1的評(píng)分更高
bool如何計(jì)算評(píng)分:
1击儡、執(zhí)行should語(yǔ)句中的兩個(gè)查詢塔沃。
2、兩個(gè)查詢的評(píng)分相加
3阳谍、乘以匹配語(yǔ)句的總數(shù)
4蛀柴、除以所有語(yǔ)句總數(shù)(這里為2,指的應(yīng)該兩個(gè)字段矫夯?鸽疾??)
文檔1中兩個(gè)字段都包含brown训貌,所以兩個(gè)match語(yǔ)句都有一個(gè)評(píng)分肮韧。
文檔2中body字段包含兩個(gè)詞,獲得較高分旺订,但title字段沒(méi)有包含任何詞,平均一下文檔2的整體分就比文檔1低超燃。
可以使用dis_max分離最大化查詢Disjunction Max Query区拳,大致意思是,將任何與任一查詢匹配的文檔作為結(jié)果返回意乓,但只將最匹配的評(píng)分作為查詢的評(píng)分結(jié)果返回:

{
    "query": {
        "dis_max": {
            "queries": [
                { "match": { "title": "Brown fox" }},
                { "match": { "body":  "Brown fox" }}
            ]
        }
    }
}

最佳字段查詢調(diào)優(yōu)

dis_max查詢會(huì)單個(gè)匹配最佳字段樱调,而忽略其他的匹配约素。(單個(gè)最佳匹配語(yǔ)句的評(píng)分作為整體評(píng)分)
可以通過(guò)指定tie_breaker字段將其他語(yǔ)句的評(píng)分也考慮其中。

{
    "query": {
        "dis_max": {
            "queries": [
                { "match": { "title": "Quick pets" }},
                { "match": { "body":  "Quick pets" }}
            ],
            "tie_breaker": 0.3
        }
    }
}

結(jié)果如下:

{
  "hits": [
     {
        "_id": "2",
        "_score": 0.14757764, (1)
        "_source": {
           "title": "Keeping pets healthy",
           "body": "My quick brown fox eats rabbits on a regular basis."
        }
     },
     {
        "_id": "1",
        "_score": 0.124275915, (1)
        "_source": {
           "title": "Quick brown rabbits",
           "body": "Brown rabbits are commonly seen."
        }
     }
   ]
}

不帶有tie_breaker參數(shù)時(shí)笆凌,評(píng)分1等于評(píng)分2
tie_breaker的評(píng)分方式:
1圣猎、獲得最佳匹配語(yǔ)句的評(píng)分
2、其他語(yǔ)句的評(píng)分結(jié)果乘以tie_breaker
3乞而、上述相加即為最后評(píng)分
tie_breaker的合理值應(yīng)該處于0.1-0.4之間

multi_match多匹配查詢

在多個(gè)字段上反復(fù)執(zhí)行相同的查詢送悔。
multi_match多匹配查詢的類型有多種,其中三種與前文的最佳字段(best_fields)爪模、多數(shù)字段(most_fields)欠啤、跨字段相匹配(cross_fields)
默認(rèn)情況查詢的類型是best_fields,例如:

{
  "dis_max": {
    "queries":  [
      {
        "match": {
          "title": {
            "query": "Quick brown fox",
            "minimum_should_match": "30%"
          }
        }
      },
      {
        "match": {
          "body": {
            "query": "Quick brown fox",
            "minimum_should_match": "30%"
          }
        }
      },
    ],
    "tie_breaker": 0.3
  }
}

可以使用multi_match重寫成更簡(jiǎn)潔的形式

{
    "multi_match": {
        "query":                "Quick brown fox",
        "type":                 "best_fields", (1)
        "fields":               [ "title", "body" ],
        "tie_breaker":          0.3,
        "minimum_should_match": "30%" (2)
    }
}

minimum_should_match屋灌、operator 這樣的參數(shù)會(huì)被傳遞到生成的match查詢中
匹配的字段可以使用模糊匹配的方式給出洁段,例如:

{
    "multi_match": {
        "query":  "Quick brown fox",
        "fields": "*_title"
    }
}

可以使用^為單個(gè)字段提升權(quán)重

{
    "multi_match": {
        "query":  "Quick brown fox",
        "fields": [ "*_title", "chapter_title^2" ] (1)
    }
}

多數(shù)字段

召回率:返回所有的相關(guān)文檔
精確率:不返回?zé)o關(guān)文檔
全文搜索的兩個(gè)名詞,目的是在結(jié)果的第一頁(yè)為用戶呈現(xiàn)最為相關(guān)的文檔
多字段映射共郭,首先要做的事情就是對(duì)我們的字段索引兩次祠丝,一次使用詞干模式,一次使用非詞干模式

PUT /my_index
{
    "settings": { "number_of_shards": 1 }, (1)
    "mappings": {
        "my_type": {
            "properties": {
                "title": { (2)
                    "type":     "string",
                    "analyzer": "english",
                    "fields": {
                        "std":   { (3)
                            "type":     "string",
                            "analyzer": "standard"
                        }
                    }
                }
            }
        }
    }
}

簡(jiǎn)單的查詢除嘹,兩個(gè)文檔的評(píng)分相同写半;只查詢title.std那么只有文檔2是匹配的

GET /my_index/_search
{
   "query": {
        "match": {
            "title": "jumping rabbits"
        }
    }
}

如果同時(shí)查詢兩個(gè)字段,然后使用bool查詢將結(jié)果合并憾赁,那么兩個(gè)文檔都是匹配的污朽,文檔2的分更高

GET /my_index/_search
{
   "query": {
        "multi_match": {
            "query":  "jumping rabbits",
            "type":   "most_fields", (1)
            "fields": [ "title", "title.std" ]
        }
    }
}

用廣度匹配字段title匹配盡可能多的文檔,提升召回率
同時(shí)又使用title.std作為信號(hào)將相關(guān)度更高的文檔置于結(jié)果頂部

跨字段實(shí)體搜索

多字符串查詢中龙考,我們?yōu)槊總€(gè)字段使用不同的字符串蟆肆,
而跨字段查詢是使用單個(gè)字符串在多個(gè)字段中進(jìn)行搜索。
例如我們搜索Poland Street W1V這個(gè)地址晦款,它需要匹配多個(gè)字段
假如使用motst_fields會(huì)出現(xiàn)如下問(wèn)題:
1炎功、它是為多數(shù)字段匹配任意詞設(shè)計(jì)的,而不是在所有字段中找到最匹配的
2缓溅、它不能使用operator或minimum_should_match參數(shù)來(lái)降低相關(guān)結(jié)果造成的長(zhǎng)尾效應(yīng)
3蛇损、詞頻對(duì)于每個(gè)字段是不一樣的,而且它們之間的相互影響會(huì)導(dǎo)致不好的排序結(jié)果坛怪。

字段中心式查詢

most_fields(best_fields)出現(xiàn)的問(wèn)題都是因?yàn)樗亲侄沃行氖讲樵冇倨耄皇窃~中心式的。
詞中心式:當(dāng)真正感興趣的事匹配詞的時(shí)候袜匿,它為我們查找的是最匹配的字段
問(wèn)題1:在多個(gè)字段中匹配相同的詞

GET /_validate/query?explain
{
  "query": {
    "multi_match": {
      "query":   "Poland Street W1V",
      "type":    "most_fields",
      "fields":  [ "street", "city", "country", "postcode" ]
    }
  }
}

生成的explanation解釋:

(street:poland   street:street   street:w1v)
(city:poland     city:street     city:w1v)
(country:poland  country:street  country:w1v)
(postcode:poland postcode:street postcode:w1v)

可以發(fā)現(xiàn)兩個(gè)字段都與poland匹配的文檔要比一個(gè)字段同時(shí)匹配poland和street文檔的評(píng)分高(可能是順序更啄,得出這樣的結(jié)論)
問(wèn)題2:剪掉長(zhǎng)尾
在精度匹配中,我們可以使用operator和minimum_should_match參數(shù)來(lái)消除結(jié)果中幾乎不相關(guān)的長(zhǎng)尾居灯,但是對(duì)于best_fields和most_fields中祭务,這些參數(shù)會(huì)在match查詢生成時(shí)被傳入内狗,例如操作符and,就會(huì)要求所有詞必須存在與相同字段中义锥,這顯然是不對(duì)的
問(wèn)題3:詞頻

{
    "query": {
        "multi_match": {
            "query":       "Peter Smith",
            "type":        "most_fields",
            "fields":      [ "*_name" ]
        }
    }
}

可能在結(jié)果中將“Smith Williams” 置于 “Peter Smith” 之上柳沙。
簡(jiǎn)單來(lái)說(shuō)就是smith在名字段中具有較高的IDF,他會(huì)削弱“Peter”作為名和“smith”作為姓時(shí)低IDF的所起作用拌倍。

解決方案

存在這些問(wèn)題僅僅是因?yàn)槲覀冊(cè)谔幚碇鄠€(gè)字段赂鲤,如果將這些字段組合成單個(gè)字段,問(wèn)題就會(huì)消失贰拿。

{
    "first_name":  "Peter",
    "last_name":   "Smith",
    "full_name":   "Peter Smith"
}

這樣只要查詢full_name剛才的問(wèn)題就會(huì)消失蛤袒,但是數(shù)據(jù)卻會(huì)冗余。取而代之的是另外兩種方案膨更,一個(gè)是在索引時(shí)妙真,另一個(gè)是在搜索時(shí)

自定義_all字段

_all字段的索引方式是將所有其他字段的值作為一個(gè)大字符串索引的。然而這么做并不靈活荚守,為了靈活珍德,我們可以給人名添加一個(gè)自定義_all字段,也為地址添加另一個(gè)_all字段
可以使用copy_to參數(shù)來(lái)實(shí)現(xiàn)這個(gè)功能

PUT /my_index
{
    "mappings": {
        "person": {
            "properties": {
                "first_name": {
                    "type":     "string",
                    "copy_to":  "full_name" (1)
                },
                "last_name": {
                    "type":     "string",
                    "copy_to":  "full_name" (1)
                },
                "full_name": {
                    "type":     "string"
                }
            }
        }
    }
}

first_name和last_name字段的值會(huì)被復(fù)制到full_name中
copy_to設(shè)置對(duì)multi_field無(wú)效矗漾。
多字段只是以不同方式簡(jiǎn)單索引“主”字段锈候,他們沒(méi)有自己的數(shù)據(jù)源,只要對(duì)主字段copy_to就能輕而易舉的達(dá)到相同的效果

PUT /my_index
{
    "mappings": {
        "person": {
            "properties": {
                "first_name": {
                    "type":     "string",
                    "copy_to":  "full_name", (1)
                    "fields": {
                        "raw": {
                            "type": "string",
                            "index": "not_analyzed"
                        }
                    }
                },
                "full_name": {
                    "type":     "string"
                }
            }
        }
    }
}

跨字段查詢

搜索時(shí)相應(yīng)的解決方案:使用cross_fields進(jìn)行multi_match查詢敞贡。
cross_fields是詞中心式的查詢泵琳,它將所有字段當(dāng)成一個(gè)大字段,并在每個(gè)字段中查詢每個(gè)詞

GET /_validate/query?explain
{
    "query": {
        "multi_match": {
            "query":       "peter smith",
            "type":        "most_fields",
            "operator":    "and", (1)
            "fields":      [ "first_name", "last_name" ]
        }
    }
}

得到結(jié)果表示peter和smith都必須同時(shí)出現(xiàn)在相同字段中誊役,要么是first_name获列,要么last_name

(+first_name:peter +first_name:smith)
(+last_name:peter  +last_name:smith)

然而詞中心式會(huì)使用以下邏輯,意味著peter和smith都必須出現(xiàn)蛔垢,但是可以出現(xiàn)在任意字段中

+(first_name:peter last_name:peter)
+(first_name:smith last_name:smith)

cross_fields類型首先分析查詢字符串并生成一個(gè)詞列表击孩,然后它從所有字段中依次搜索每個(gè)詞。
這種不同的查詢方式自然就解決了前兩個(gè)問(wèn)題鹏漆。
至于IDF問(wèn)題巩梢,它通過(guò)混合不同字段逆向索引文檔頻率的方式解決了詞頻的問(wèn)題。

GET /_validate/query?explain
{
    "query": {
        "multi_match": {
            "query":       "peter smith",
            "type":        "cross_fields", (1)
            "operator":    "and",
            "fields":      [ "first_name", "last_name" ]
        }
    }
}
+blended("peter", fields: [first_name, last_name])
+blended("smith", fields: [first_name, last_name])

換句話說(shuō)艺玲,它會(huì)在兩個(gè)字段字段中查找smith的IDF括蝠,然后使用最小值作為兩個(gè)字段的IDF。
Tip:為了讓cross_fields查詢以最優(yōu)的方式工作饭聚,所有的字段都必須使用相同的分析器忌警,具有相同分析器的字段會(huì)被分組在一起作為混合字段使用。
如果包括了不同分析器的字段若治,它們會(huì)以best_fields的相同方式加入到查詢結(jié)果中慨蓝。
例如將title字段加入到之前的查詢,explanation解釋如下:

(+title:peter +title:smith)
(
  +blended("peter", fields: [first_name, last_name])
  +blended("smith", fields: [first_name, last_name])
)

當(dāng)在使用minimum_should_match和operator參數(shù)時(shí)端幼,這點(diǎn)尤為重要

按字段提高權(quán)重

使用cross_fields和_all相比礼烈,其中一個(gè)優(yōu)勢(shì)就是它可以在搜索時(shí)為單個(gè)字段提升權(quán)重
正如前文提到的^
自定義單字段查詢能否優(yōu)于多字段查詢,取決于在多字段與單字段自定義_all之間代價(jià)的權(quán)衡婆跑。

Exact-Value精確值字段

將not_analyzed字段與 multi_match中analyzed字段混在一起沒(méi)有多大用處此熬。
如前文的查詢,假如title是not_analyzed

title:peter smith
(
    blended("peter", fields: [first_name, last_name])
    blended("smith", fields: [first_name, last_name])
)

es會(huì)將peter smith完整的字符串作為查詢條件來(lái)搜索滑进,所以需要在multi_match查詢中避免使用not_analyzed字段

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末犀忱,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子扶关,更是在濱河造成了極大的恐慌阴汇,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件节槐,死亡現(xiàn)場(chǎng)離奇詭異搀庶,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)铜异,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門哥倔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人揍庄,你說(shuō)我怎么就攤上這事咆蒿。” “怎么了蚂子?”我有些...
    開(kāi)封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵沃测,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我缆镣,道長(zhǎng)芽突,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任董瞻,我火速辦了婚禮寞蚌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘钠糊。我一直安慰自己挟秤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布抄伍。 她就那樣靜靜地躺著艘刚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪截珍。 梳的紋絲不亂的頭發(fā)上攀甚,一...
    開(kāi)封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天箩朴,我揣著相機(jī)與錄音,去河邊找鬼秋度。 笑死炸庞,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的荚斯。 我是一名探鬼主播埠居,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼事期!你這毒婦竟也來(lái)了滥壕?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤兽泣,失蹤者是張志新(化名)和其女友劉穎绎橘,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體撞叨,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡金踪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了牵敷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胡岔。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖枷餐,靈堂內(nèi)的尸體忽然破棺而出靶瘸,到底是詐尸還是另有隱情,我是刑警寧澤毛肋,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布怨咪,位于F島的核電站,受9級(jí)特大地震影響润匙,放射性物質(zhì)發(fā)生泄漏诗眨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一孕讳、第九天 我趴在偏房一處隱蔽的房頂上張望匠楚。 院中可真熱鬧,春花似錦厂财、人聲如沸芋簿。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)与斤。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間撩穿,已是汗流浹背磷支。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留食寡,地道東北人齐唆。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像冻河,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子茉帅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容