elasticsearch 搜索介紹

前言

type 類型介紹

text:

????????????默認分詞,將字符串分成若干個詞,創建索引。同時,保存一份不分詞的字符串,保存在索引中(默認最多保存256個字符)。例:“hello world” ,filed索引:hello,world ,field.keyword索引中存放hello word。

一.? 查詢

????????term query(短語搜索)

????查詢字符不分詞,將查詢的條件當做一個整體進行查詢

????????filter query(過濾搜索)

????????優勢在于會caching,增加或刪除數據,會自動更新。實際上緩存的并不是一個完整的doc list數據結果,而是將filter bitset緩存起來(對于小的數據量,是不會進行緩存的),下次不需要掃碼倒排索引了。大部分情況下,是在query之前執行,盡量過濾到盡可能多的數據。query會計算相關度分數,并根據相關度分數進行排序。而filter只是過濾結果,不進行相關的計算和排序。

????????math query(匹配搜索)

????????默認分詞,進行精確度查詢時,可以指定operator為and,進行查詢。示例如下:{"query":{"match":{"title":{"query":"java elasticsearch","operator":"and"}}}}; 也可以指定匹配率,進行查詢。示例如下:{"query":{"match":{"title":{"query":"java elasticsearch test hadoop","minimum_should_match":"75%"}}}}

????????prefix query (前綴搜索)

? ? 前綴搜索,查詢以搜索詞開始的doc。例如查詢:C4,則可以查詢到C412,但是不能查詢到2C4。類似mysql的模糊搜索中的"C4%"。語法:{"query":{"prefix":{"position.keyword":{"value":"C4"}}}}

?????????wildcard query(通配符搜索)

? ? 通配符搜索,?代表以為字符,*代表0到任意多個字符。性能比較差,需要掃描所有的倒排索引。盡力不要用。查詢語法:{"query":{"wildcard":{"position.keyword":{"value":"*s?f*"}}}}

? ??????regexp query(正則搜索)

? ? 正則搜索,[0-9]:指定范圍的數字,[a-z]:指定范圍的字符,. :代表一個字符,+:代表前面的正則表達式可以出現一個到多個。查詢語法:{"query":{"regexp":{"position.keyword":{"value":"s[a-z].+"}}}}

二.? 查詢策略

? ? ?best fields?? 查詢策略

? ? ? ?dis_max參數:多條件查詢時,盡量將一個條件中匹配度最高的排在前面,而不是將多個條件組合匹配度高的排在前面。例:查詢條件:“title”:“java elasticsearch” ,content:“java elasticsearch”,不是將分詞后的查詢中既滿足title查詢條件,又滿足content查詢條件的排在前面。而是分別對各個查詢條件進行查詢,分別計算相關度分數,然后將其中查詢相關分數最高的排在前面。語法:{"query":{"dis_max":{"queries":[{"match":{"title":"java elasticsearch"}},{"match":{"content":"java elasticsearch"}}]}}}

? ? ? ?tie_breaker參數: dis_max 只取最大的,不考慮其他查詢條件的相關度分數,會出現查詢結果特別不準確的情況。這時候需要引入tie_breaker參數。其他的查詢條件*tie_breaker ,再加上最大相關度分數。綜合計算新的相關度分數。語法:{"query":{"dis_max":{"queries":[{"match":{"title":"java elasticsearch"}},{"match":{"content":"java elasticsearch"}}],"tie_breaker":0.3}}}

????????語法:{"query":{"multi_match":{"query":"use china finance manager","type":"best_fields","fields":["country","position"]}}}

most fields 查詢策略

????????盡可能將匹配更多field的結果優先返回回來,如下(會將country和postion都匹配的優先返回)。? 語法:{"query":{"multi_match":{"query":"use china finance manager","type":"most_fields","fields":["country","position"]}}}

????????弊端:知道盡可能到的field匹配的doc,而不是完全匹配的doc;不能使用minimun_should_match 去掉不滿足條件的長尾結果。 相關度分數計算方法很復雜,可能會將出現頻率低filed的匹配計算的分數特別大,導致優先返回,跟預計的搜索結果相差很大 。

????????解決思路:將多個fields 合并為一個field。進行查詢。es中提供copy_to 屬性。可以將多個field合并到一個field。

cross filed 查詢策略?

????????盡可能多的field中匹配,而不是某個field中匹配。跟most_fields的區別在于cross_fields支持operator屬性,可以滿足每個term都必須在一個filed中出現。不加operator的話,跟most_fields查詢結果幾無差別。查詢語法:{"query":{"multi_match":{"query":"manager china","type":"cross_fields","operator":"and","fields":["position","country"]}}}

三. 近似查詢

1.match_phase? 模糊匹配

????????類似于sql查詢的模糊查詢。例如:查詢java spark ,是將查詢條件作為一個短語進行模糊查詢。要求java和spark符合查詢條件,且必須相連。查詢原理:查找到既包含java,又包含spark的doc之后,計算java和spark的位置。如果正好相鄰且滿足查詢時的順序,則返回。查詢語法:{"query":{"match_phrase":{"position":{"query":"senor software"}}}}

2. proximiy match 近似匹配?

????????使用match_phase和slop 進行移位查詢。

????????類似模糊查詢,但是可以指定term之間相距的位置差。例如:java? spark 查詢,指定slop為1.則不僅可以模糊查詢到java spark 相連的數據,還可以查詢到java and spark中間間隔為1的數據;同理指定為n,則允許java和spark最多相差n位。查詢語法:{"query":{"match_phrase":{"position":{"query":"senor software","slop":2}}}}

3.?match_phrase_prefix 前綴近似匹配

? ?原理和match_phrase相似,唯一的區別是會將最后一個term作為前綴進行搜索。但是只會將最后一個term作為前綴。max_expansions參數:指定term最多匹配多少個。查詢語法:{"query":{"match_phrase_prefix":{"position.keyword":{"query":"technique so","max_expansions":10}}}}

4.解決問題:

????????解決即想查詢java,又想查詢spark。并且盡可能將java和spark相距越近的排在前面,相距遠的排在后面,只匹配一個的term的排在最后面。

查詢語法:{"query":{"bool":{"must":[{"match":{"position":"senor manager"}}],"should":[{"match_phrase":{"position":{"query":"senor manager","slop":1}}}]}}}

? ? ? ? rescore: 重打分

語法:{"query":{"match":{"position":"senor manager"}},"rescore":{"query":{"rescore_query":{"match_phrase":{"position":{"query":"senor manager","slop":1}}}},"window_size":50}}? ?其中:window_size表示對前多少個重打分。slop 標識term之間position相差的位數。

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