https://www.iteblog.com/archives/1741.htmlhtml
基本匹配查詢主要有兩種形式:正則表達式
(1)使用Search Lite API,並將全部的搜索參數都經過URL傳遞;緩存
GET /_all/tweet/_search?q=tweet:elasticsearchelasticsearch
查詢type是tweet而且字段「tweet」包含"elasticsearch"的documentide
(2)使用Elasticsearch DSL,其能夠經過傳遞一個JSON請求來獲取結果。性能
GET /_search
{
"query": {
"match": {
"tweet":"elasticsearch"優化}
}
}ui
DSL方式提供了更加靈活的方式來構建更加複雜的查詢,甚至指定你想要的返回結果。spa
例如:指定須要返回結果的數量,開始的偏移量(這在分頁的狀況下很是有用),須要返回document中的哪些字段以及高亮關鍵字:代理
{
"query": {
"match" : {
"title" : "in action" //查詢title中包含in或action
}
},
"size": 2, //返回結果的數量
"from": 0, //開始的偏移量
"_source": [ "title", "summary", "publish_date" ], //指定返回document中的字段
"highlight": { //高亮title字段
"fields" : {
"title" : {}
}
}
}
使用muliti_match查詢:
{
"query": {
"multi_match" : {
"query" : "elasticsearch guide",
//指定查詢的多個字段,title或summary字段中包含elasticsearch或guide
"fields": ["title", "summary"]
}
}
}
在查詢中改變特定字段的相關度。
{
"query": {
"multi_match" : {
"query" : "elasticsearch guide",
"fields": ["title", "summary^3"] //增大summary的相關度,權重調整爲3
}
},
"_source": ["title", "summary", "publish_date"]
}
【注】Boosting不只僅意味着計算出來的分數(calculated score)直接乘以boost factor,最終的boost value會通過歸一化以及其餘一些內部的優化。
在查詢條件中使用AND/OR/NOT操做符,這就是布爾查詢(Bool Query)。Bool查詢如今包括四種子句:must,filter,should,must_not。
{
"query": {
"bool": {
"must": {
"bool" : { "should": [
{ "match": { "title": "Elasticsearch" }},
{ "match": { "title": "Solr" }} ] }
},
"must": { "match": { "authors": "clinton gormely" }},
"must_not": { "match": {"authors": "radu gheorge" }}
}
}
}
查詢title中出現Elasticsearch或者Solr關鍵字的圖書,圖書的做者是clinton gormley,但沒有radu gheorge
【注】filter查詢比query快:
query的時候,會先比較查詢條件,而後計算分值,最後返回文檔結果;
而filter則是先判斷是否知足查詢條件,若是不知足,會緩存查詢過程(記錄該文檔不知足結果);知足的話,就直接緩存結果並返回。
綜上所述,filter快在兩個方面:
- 1 對結果進行緩存
- 2 避免計算分值
模糊查詢能夠在Match
和 Multi-Match
查詢中使用以便解決拼寫的錯誤,模糊度是基於Levenshtein distance計算與原單詞的距離。
{
"query": {
"multi_match" : {
"query" : "comprihensiv guide",
"fields": ["title", "summary"],
"fuzziness": "AUTO" //指定模糊查詢
}
},
"_source": ["title", "summary", "publish_date"],
"size": 1
}
【注】將fuzziness的值指定爲
AUTO
,其在term的長度大於5的時候至關於指定值爲2。然而80%的人拼寫錯誤的編輯距離(edit distance)爲1,全部若是你將fuzziness設置爲1可能會提升你的搜索性能。
通配符查詢容許咱們指定一個模式來匹配,而不須要指定完整的trem。?
將會匹配任何字符;*
將會匹配零個或者多個字符。
{
"query": {
"wildcard" : {
"authors" : "t*" //author中包含以t開頭
}
},
"_source": ["title", "authors"],
"highlight": {
"fields" : {
"authors" : {}
}
}
}
{
"query": {
"regexp" : {
"authors" : "t[a-z]*y" //以t開頭,中間包含若干個a-z,以y結束,使用正則表達式
}
},
"_source": ["title", "authors"],
"highlight": {
"fields" : {
"authors" : {}
}
}
}
匹配短語查詢要求查詢字符串中的trems都出現Document中或者trems按照輸入順序依次出如今結果中。
能夠指定slop
參數,來控制輸入的trems之間有多少個單詞(距離)仍然可以搜索到。
{
"query": {
"multi_match": {
"query": "search engine",
"fields": [
"title",
"summary"
],
"type": "phrase", //指定匹配詞組
"slop": 3 //指定詞組中單詞之間的距離不大於3
}
},
"_source": [
"title",
"summary",
"publish_date"
]
}
匹配短語前綴查詢能夠指定單詞的一部分字符前綴便可查詢到該單詞,和match phrase query同樣咱們也能夠指定slop
參數;同時其還支持 max_expansions 控制最後一個單詞會被重寫成多少個前綴,也就是,控制前綴擴展成分詞的數量。
{
"query": {
"match_phrase_prefix": { //匹配前綴查詢
"summary": {
"query": "search en",
"slop": 3, //距離爲3
"max_expansions": 10 //前綴查詢可被擴展到的詞條數
}
}
},
"_source": [
"title",
"summary",
"publish_date"
]
}
【注】匹配短語前綴查詢是有性能消耗的,全部使用以前須要當心。
query_string查詢提供了一種手段可使用一種簡潔的方式運行multi_match queries, bool queries, boosting, fuzzy matching, wildcards, regexp以及range queries的組合查詢。
{
"query": {
"query_string" : {
"query": "(search~1 algorithm~1) AND (grant ingersoll) OR (tom morton)",
"fields": ["_all", "summary^2"]
}
},
"_source": [ "title", "summary", "authors" ],
"highlight": {
"fields" : {
"summary" : {}
}
}
}
simple_query_string
是query_string
的另外一種版本,其更適合爲用戶提供一個搜索框中,由於其使用+/|/- 分別替換AND/OR/NOT,若是用輸入了錯誤的查詢,其直接忽略這種狀況而不是拋出異常。
{
"query": {
"simple_query_string" : { //簡單查詢字符串
"query": "(saerch~1 algorithm~1) + (grant ingersoll) | (tom morton)",
"fields": ["_all", "summary^2"]
}
},
"_source": [ "title", "summary", "authors" ],
"highlight": {
"fields" : {
"summary" : {}
}
}
}
{
"query": {
"term" : { //查詢publisher = manning
"publisher": "manning"
}
},
"_source" : ["title","publish_date","publisher"]
}
{
"query": {
"terms" : { //查詢多個匹配,或
"publisher": ["oreilly", "packt"]
}
}
}
詞查詢結果和其餘查詢結果同樣能夠很容易地對其進行排序,並且咱們能夠對輸出結果按照多層進行排序。
{
"query": {
"term" : {
"publisher": "manning"
}
}, //查詢publisher = manning的圖書
"_source" : ["title","publish_date","publisher"],
"sort": [ //對查詢到的結果排序,按照出版日期或title
{ "publish_date": {"order":"desc"}},
{ "title": { "order": "desc" }}
]
}
{
"query": {
"range" : { //範圍查詢,按照出版日期
"publish_date": {
"gte": "2015-01-01",
"lte": "2015-12-31"
}
}
},
"_source" : ["title","publish_date","publisher"]
}
範圍查詢能夠應用於日期,數字以及字符類型的字段。
過濾查詢容許咱們對查詢結果進行篩選。
{
"query": {
"filtered": { //返回過濾以後的結果,5.0以後再也不使用了
"query" : {
"multi_match": { //多字段匹配查詢
"query": "elasticsearch",
"fields": ["title","summary"]
}
},
"filter": { //對範圍進行過濾
"range" : {
"num_reviews": {
"gte": 20
}
}
}
}
},
"_source" : ["title","summary","publisher", "num_reviews"]
}
【注】過濾查詢(Filtered queries)並不強制過濾條件中指定查詢。若是沒有指定查詢條件,則會運行
match_all
查詢,其將會返回index中全部文檔,而後對其進行過濾。在實際運用中,過濾器應該先被執行,這樣能夠減小須要查詢的範圍。並且,第一次使用fliter以後其將會被緩存,這樣會對性能代理提高。
Filtered queries在Elasticsearch 5.0中移除了,咱們可使用
bool
查詢來替換它。下面是使用bool查詢來實現上面同樣的查詢效果,返回結果同樣 。{
"query": {
"bool": {
"must" : {
"multi_match": {
"query": "elasticsearch",
"fields": ["title","summary"]
}
},
"filter": {
"range" : {
"num_reviews": {
"gte": 20
}
}
}
}
},
"_source" : ["title","summary","publisher", "num_reviews"]
}
{
"query": {
"filtered": {
"query" : {
"multi_match": {
"query": "elasticsearch",
"fields": ["title","summary"]
}
},
"filter": {
"bool": {
"must": {
"range" : { "num_reviews": { "gte": 20 } }
},
"must_not": {
"range" : { "publish_date": { "lte": "2014-12-31" } }
},
"should": {
"term": { "publisher": "oreilly" }
}
}
}
}
},
"_source" : ["title","summary","publisher", "num_reviews", "publish_date"]
}
在某些場景下,你可能想對某個特定字段設置一個因子(factor),並經過這個因子計算某個文檔的相關度(relevance score)。這是典型的基於文檔(document)的重要性來擡高其相關性的方式。
{
"query": {
"function_score": { //
"query": {
"multi_match" : {
"query" : "search engine",
"fields": ["title", "summary"]
}
},
"field_value_factor": {
"field" : "num_reviews",
"modifier": "log1p",
"factor" : 2
}
}
},
"_source": ["title", "summary", "publish_date", "num_reviews"]
}
Decay Functions主要有三種:分別是linear
、exp
以及gauss
,分別用於操做數字字段(numeric fields)、日期字段(date fields)以及經/緯度的地理點。這三種Decay Functions都接收如下四種參數:
一、origin
:中心點,或者是該字段最有可能的值。全部落在中心點的文檔的得分(_score
)都是1.0;
二、scale
:衰減率。指的是一個文檔距離origin
得到_score
的須要減小多少;
三、decay
:衰減。指的是一個文檔在相對於origin的scale距離應該獲得的_score
,默認值是0.5;
四、offset
:偏移,全部落入-offset < = origin <= +offset
範圍的值都將獲得1.0的_score
。
下圖展現了這三種Decay Functions的區別:
gauss 衰減速度先慢後快再慢,exp 衰減速度先快後慢,lin 直線衰減,在0分外的值都是0分,如何選擇取決於你想要你的score以什麼速度衰減。
{
"query": {
"function_score": {
"query": {
"multi_match" : {
"query" : "search engine",
"fields": ["title", "summary"]
}
},
"functions": [
{
"exp": {
"publish_date" : {
"origin": "2014-06-15",
"offset": "7d",
"scale" : "30d"
}
}
}
],
"boost_mode" : "replace"
}
},
"_source": ["title", "summary", "publish_date", "num_reviews"]
}
若是內置的scoring functions知足不了你的需求,咱們就可使用Script Scoring,經過指定一個Groovy script來計算分數。
計算分數的腳本以下:
publish_date = doc[
'publish_date'
].value
num_reviews = doc[
'num_reviews'
].value
if
(publish_date > Date.parse(
'yyyy-MM-dd'
, threshold).getTime()) {
my_score = Math.log(
2.5
+ num_reviews)
}
else
{
my_score = Math.log(
1
+ num_reviews)
}
return
my_score
{
"query"
: {
"function_score"
: {
"query"
: {
"multi_match"
: {
"query"
:
"search engine"
,
"fields"
: [
"title"
,
"summary"
]
}
},
"functions"
: [
{
"script_score"
: {
"params"
: {
"threshold"
:
"2015-07-30"
},
"script"
:
"publish_date = doc['publish_date'].value; num_reviews = doc['num_reviews'].value; if (publish_date > Date.parse('yyyy-MM-dd', threshold).getTime()) { return log(2.5 + num_reviews) }; return log(1 + num_reviews);"
}
}
]
}
},
"_source"
: [
"title"
,
"summary"
,
"publish_date"
,
"num_reviews"
]
}