Query DSL

Neil Zhu,簡書ID Not_GOD,University AI 創(chuàng)始人 & Chief Scientist,致力于推進(jìn)世界人工智能化進(jìn)程。制定并實(shí)施 UAI 中長期增長戰(zhàn)略和目標(biāo),帶領(lǐng)團(tuán)隊(duì)快速成長為人工智能領(lǐng)域最專業(yè)的力量。
作為行業(yè)領(lǐng)導(dǎo)者,他和UAI一起在2014年創(chuàng)建了TASA(中國最早的人工智能社團(tuán)), DL Center(深度學(xué)習(xí)知識(shí)中心全球價(jià)值網(wǎng)絡(luò)),AI growth(行業(yè)智庫培訓(xùn))等,為中國的人工智能人才建設(shè)輸送了大量的血液和養(yǎng)分。此外,他還參與或者舉辦過各類國際性的人工智能峰會(huì)和活動(dòng),產(chǎn)生了巨大的影響力,書寫了60萬字的人工智能精品技術(shù)內(nèi)容,生產(chǎn)翻譯了全球第一本深度學(xué)習(xí)入門書《神經(jīng)網(wǎng)絡(luò)與深度學(xué)習(xí)》,生產(chǎn)的內(nèi)容被大量的專業(yè)垂直公眾號(hào)和媒體轉(zhuǎn)載與連載。曾經(jīng)受邀為國內(nèi)頂尖大學(xué)制定人工智能學(xué)習(xí)規(guī)劃和教授人工智能前沿課程,均受學(xué)生和老師好評(píng)。

Query DSL

elasticsearch提供了一整套機(jī)遇JSON的查詢DSL語言來定義查詢。一般來說,會(huì)包含基本的term和前綴查詢。同樣也包含復(fù)合查詢?nèi)鏱ool查詢。查詢也擁有過濾器,諸如filtered或者constant_score的查詢(以特定的過濾查詢)。

請(qǐng)將查詢DSL當(dāng)作查詢的一個(gè)抽象語法樹(AST)。某些查詢可以包含其他的查詢(例如bool查詢),另外一些則包含過濾器(如constant_score),還有就是包含兩者的(如filtered)。這些查詢都可以包含查詢列表種的任意的查詢,或者任何過濾器列表種的一個(gè)。這樣就能夠構(gòu)建出相當(dāng)復(fù)雜的(和有趣的)查詢。

查詢和過濾器都可以在不同的API里使用。例如,在一個(gè)搜索查詢,或者作為一個(gè)facet filter。這個(gè)章節(jié)解釋了查詢和過濾兩個(gè)部分,從而可以形成可以使用的抽象語法樹(AST)。

由于沒有打分的過程,并且自動(dòng)的cache,所以過濾器比一般查詢降低超過一個(gè)數(shù)量級(jí),因此它們是相當(dāng)好用的。

Queries

按照一個(gè)通用的規(guī)則,查詢應(yīng)當(dāng)盡可能被過濾器所替代:

  • 全文檢索
  • 結(jié)果依賴于一個(gè)相關(guān)性的打分

match查詢

match查詢接受文本/數(shù)值/日期,分析之,構(gòu)造出一個(gè)查詢。例如:

{
    "match" : {
        "message" : "This is a test"
    }
}

注意,message是field的名稱,可以使用任何一個(gè)field的名稱來代替(包含_all)。

match查詢的類型

boolean

boolean 默認(rèn)的match查詢就是布爾型(boolean),這是指對(duì)目標(biāo)文本進(jìn)行分析,分析后便構(gòu)造出一個(gè)布爾查詢。operator標(biāo)記可以被設(shè)置為or或者and來控制布爾語句(默認(rèn)為or)。should語句最小值可以使用minimum_should_match參數(shù)來設(shè)置。

analyzer可以被設(shè)置來控制分析器(analyzer)將要執(zhí)行的對(duì)文本的分析過程。默認(rèn)被設(shè)為field顯式的mapping定義或者默認(rèn)搜索分析器。

fuzziness允許fuzzy matching基于被查詢的field的類型。見Fuzziness那章。

prefix_lengthmax_expansions可以被設(shè)置來控制fuzzy過程。如果fuzzy選項(xiàng)被設(shè)置,那么查詢會(huì)使用constant_score_rewrite作為其重寫方法(rewrite method)的參數(shù)。fuzzy_rewrite參數(shù)允許控制查詢的如何被重寫。

下面是一個(gè)提供了額外參數(shù)的(注意其結(jié)構(gòu)的微妙——變化message是field名稱)例子:

{
    "match" : {
        "message" : {
            "query" : "this is a test",
            "operator" : "and"
        }   
    }
}

zero_terms_query:如果使用的analyzer移除了一個(gè)查詢中所有的token(如stop filter所做的那樣),默認(rèn)行為是不匹配任何文章。為了改變使得zero_terms_query選項(xiàng)可以被使用,其接受none(默認(rèn))和all對(duì)應(yīng)于match_all查詢。

{
    "match" : {
        "message" : {
            "query" : "to be or not to be",
            "operator" : "and",
            "zero_terms_query": "all"
        }
    }
}

cutoff_frequency允許設(shè)置一個(gè)絕對(duì)或者相對(duì)的文檔頻率,其中高頻項(xiàng)被移進(jìn)一個(gè)可選的子查詢,并且當(dāng)使用or連接的低頻項(xiàng)的一個(gè)或者所有用and相連的低頻項(xiàng)匹配時(shí)記分。

這種查詢可以在運(yùn)行時(shí)動(dòng)態(tài)處理stopwords,并且是domain獨(dú)立的,也并不要求一個(gè)停詞文件。阻止打分/迭代高頻term和只有一個(gè)更加明顯/低頻term匹配一個(gè)文檔時(shí)才會(huì)考慮這些term。但是,如果所有查詢term超過給定的cutoff_frequency,查詢自動(dòng)轉(zhuǎn)化為一個(gè)純合取(and)查詢來確??焖賵?zhí)行。

cutoff_frequency如果在[0..1)區(qū)間中,則與index中的文檔數(shù)相關(guān)。如果超過1.0,則為絕對(duì)值。

下面是展示包含stopwords的查詢

{
    "match" : {
        "message" : {
            "query" : "to be or not to be",
            "cutoff_frequency" : 0.001
        }
    }
}
phrase

match_phrase查詢分析文本并從分析了的文本中創(chuàng)建一個(gè)phrase查詢。例如:

{
    "match_phrase" : {
        "message" : "This is a test"
    }
}

由于match_phrase僅是match查詢的一種type,它可以如下使用:

{
    "match" : {
        "message" : {
            "query" : "this is a test",
            "type" : "phrase"
        }
    }
} 

phrase查詢匹配可設(shè)置的任意順序的slop(默認(rèn)為0)個(gè)數(shù)的term。Transposed term擁有2的slop。

analyzer可以被設(shè)置來控制那個(gè)分析器來執(zhí)行對(duì)文本的分析過程。默認(rèn)為field顯式的mapping定義,或者默認(rèn)的搜索分析器,例如:

{
    "match_phrase" : {
        "message" : {
            "query" : "this is a test",
            "analyzer" : "my_analyzer"
        }
    }
}
match_phrase_prefix

match_phrase_prefixmatch_phrase相同,除了它允許前綴匹配。except that it allows for prefix matches on the last term in the text.

{
    "match_phrase_prefix" : {
        "message" : "this is a test"
    }
}

或:

{
    "match" : {
        "message" : {
            "query" : "this is a test",
            "type" : "phrase_prefix"
        }
    }
}

它接受同樣的參數(shù)作為phrase type。另外,它同樣接受max_expansions參數(shù),該參數(shù)可以控制最后項(xiàng)將要被擴(kuò)展的前綴的個(gè)數(shù)。強(qiáng)烈建議將其設(shè)置為一個(gè)可接受的值來空查詢的執(zhí)行時(shí)間。例如:

{
    "match_phrase_prefix" : {
        "message" : {
            "query" : "this is a test",
            "max_expansions" : 10
        }
    }
}

與query_string/field的比較

查詢的匹配(match)家族并不會(huì)走“查詢parsing”的過程。并不支持field名的前綴,wildcard字符或者其他高級(jí)特性。因此,它失敗的幾率非常?。蛘咄耆粫?huì)出現(xiàn),并且當(dāng)僅需要分析和運(yùn)行一個(gè)文本作為查詢行為(text search box常常這么干)。另外,phrase_prefix類型可以提供一個(gè)“as you type”行為來自動(dòng)加載搜索結(jié)果。

其余選項(xiàng)

  • lenient - 如設(shè)置為true將會(huì)導(dǎo)致基于格式的失?。ɡ缣峁┪谋窘o一個(gè)數(shù)值類型的field)被忽略。默認(rèn)為false。

multi match query

多重匹配查詢建立在match查詢的基礎(chǔ)上:

{
  "multi_match" : {
    "query":    "this is a test",          ..... 1
    "fields": [ "subject", "message" ]     ..... 2
  }
}
  1. 查詢?cè)~
  2. 查詢的域

fields和每個(gè)field的boosting

fields可以使用通配符(wildcards),如:

{
    "multi_match" : {
        "query" : "Will Smith",
        "fields" : ["title", "*_name"]   ..... 1
    }
}
  1. 查詢title、first_namelast_namefield。

獨(dú)立的field可以使用caret(^)符號(hào)進(jìn)行增加額度:

{
    "multi_match" : {
        "query" : "this is a test",
        "fields" : [ "subject^3", "messsage" ] .....1
    }
}

use_dis_max

1.1.0中反對(duì)使用。使用type:best_fieldstype:most_fields代替。見multi_match查詢

默認(rèn),multi_match查詢對(duì)每個(gè)field均生成了一個(gè)match子句,接著將這些子句包含進(jìn)一個(gè)dis_max查詢。通過設(shè)置use_dis_maxfalse,他們將被包含進(jìn)一個(gè)bool查詢而非dis_max查詢。

multi_match查詢的types

在1.1.0中添加

multi_match查詢的執(zhí)行過程依賴于type參數(shù),該參數(shù)可以被設(shè)置為:

  • best_fields -(默認(rèn))找出匹配任何field的文檔,但是使用來自best field的_score。見best_fields
  • most_fields - 找出匹配任何field并且合并來自每個(gè)field的_score。見most_fields
  • cross_fields - 將擁有相同analyzer的field當(dāng)作一個(gè)大的field。查找在任何field中的每個(gè)word。見cross_fields
  • phrase - 對(duì)每個(gè)field上運(yùn)行一個(gè)match_phrase查詢并合并來自每個(gè)field的_score。參見phrasephrase_prefix
  • phrase_prefix - 在每個(gè)field上運(yùn)行一個(gè)match_phrase_prefix查詢并合并來自每個(gè)field的_score。參見phrasephrase_prefix

best_fields

best_fields類型是當(dāng)你搜索在同樣的field中多個(gè)word時(shí)最有用的。The best_fields type is most useful when you are searching for multiple words best found in the same field. 例如,“brown fox”在一個(gè)單一field比“brown”在一個(gè)field而“fox”在另一個(gè)field中更有可能。

best_fields類型對(duì)每個(gè)field均生成一個(gè)match_query,將他們包含在一個(gè)dis_max查詢中,來找到單一的最佳匹配field。例如,下面這個(gè)查詢:

{
    "multi_match" : {
        "query" : "brown fox",
        "type" : "best_fields",
        "fields" : ["subject", "message"],
        "tie_breaker" : 0.3
    }
}

將會(huì)被執(zhí)行為以下查詢:

{
  "dis_max": {
    "queries": [
      { "match": { "subject": "brown fox" }},
      { "match": { "message": "brown fox" }}
    ],
    "tie_breaker": 0.3
  }
}

正常來說,best_fields類型使用單一最有匹配field的打分,但是如果tie_breaker被指定,那么它會(huì)以如下方式計(jì)算打分:

  • 分?jǐn)?shù)來自最優(yōu)匹配field
  • 加上來自其他匹配field的tie_breaker * _score

同樣,接受analyzer, boost, operator, minimum_should_match, fuzziness, prefix_length, max_expansions, rewrite, zero_terms_query and cutoff_frequency,這些在match query中已經(jīng)解釋過了。

operatorminimum_should_match
這兩個(gè)類型是以field為中心的——他們對(duì)每個(gè)field產(chǎn)生一個(gè)match查詢。這是指operatorminimum_should_match參數(shù)被獨(dú)立地應(yīng)用在每個(gè)field上,這可能不是你本來想要的效果
例如:

{
 "multi_match" : {
   "query":      "Will Smith",
   "type":       "best_fields",
   "fields":     [ "first_name", "last_name" ],
   "operator":   "and"  ..... 1
 }
}
  1. 要求所有項(xiàng)都要出現(xiàn)
    這個(gè)查詢就執(zhí)行為:
    (+first_name:will +first_name:smith) | (+last_name:will +last_name:smith)
    也就是說,所有term必須在一個(gè)單一的field中以匹配一篇文檔

most_fields

most_fields類型是在查詢多個(gè)field包含以不同方式分析的同樣的文本時(shí)最為有效。例如,main field可能會(huì)包含同義詞、stemming和不包含變音符的項(xiàng)(term)第二field可能包含原始term,第三field可能包含“招牌”。通過合并來自所有這三個(gè)field的分?jǐn)?shù),我們可以匹配主field的盡可能多的文檔,但是使用第二和第三個(gè)field來推送最相似的結(jié)果到返回列表的list。

下面的這個(gè)查詢:

{
  "multi_match" : {
    "query":      "quick brown fox",
    "type":       "most_fields",
    "fields":     [ "title", "title.original", "title.shingles" ]
  }
}

將被執(zhí)行為:

{
  "bool": {
    "should": [
      { "match": { "title":          "quick brown fox" }},
      { "match": { "title.original": "quick brown fox" }},
      { "match": { "title.shingles": "quick brown fox" }}
    ]
  }
}

來自每個(gè)match子句的分?jǐn)?shù)將被加起來,然后初上match子句的數(shù)目。

同樣的,它也接受analyzer, boost, operator, minimum_should_match, fuzziness, prefix_length, max_expansions, rewrite, zero_terms_query and cutoff_frequency,這些在match query中已經(jīng)解釋過了。

phrase和phrase_prefix

phrasephrase_prefix類型和best_fields行為類似,但是他們使用了一個(gè)match_phrasematch_phrase_prefix查詢而不是一個(gè)match查詢。

這個(gè)查詢:

{
  "multi_match" : {
    "query":      "quick brown f",
    "type":       "phrase_prefix",
    "fields":     [ "subject", "message" ]
  }
}

就如同:

{
  "dis_max": {
    "queries": [
      { "match_phrase_prefix": { "subject": "quick brown f" }},
      { "match_phrase_prefix": { "message": "quick brown f" }}
    ]
  }
}

同樣,它接受analyzer``boost``slop``zero_terms_query,這些在match query中已經(jīng)解釋過了。phrase_prefix額外接受max_expansions。

cross_fields

cross_field類型特別是在遇到結(jié)構(gòu)化文檔并且多個(gè)field應(yīng)當(dāng)match時(shí)尤為好用。例如,當(dāng)查詢first_namelast_namefield“Will Smith”時(shí),best match可能會(huì)將“Will”放在一個(gè)field中,而把“Smith”放進(jìn)另一個(gè)。

這就如同most_fields那樣,但是有兩個(gè)問題。一個(gè)問題是operatorminimum_should_match是按每field進(jìn)行的,而不是每個(gè)term。
第二個(gè)問題與相關(guān)性有關(guān)系:不同的term頻率在first_namelast_namefield可以產(chǎn)生難以預(yù)料的結(jié)果。
例如,假設(shè)我們有兩個(gè)人“Will Smith”和“Smith Jones”?!癝mith”作為一個(gè)last name是相當(dāng)普通的(所以就會(huì)降低其重要性),但是“Smith”作為一個(gè)first name是罕見的(因此就給它較大的重要性)。
如果我們搜索“Will Smith”,“Smith Jones”文檔將出現(xiàn)在更好的匹配“Will Smith”的結(jié)果中,因?yàn)?code>first_name:smith的分?jǐn)?shù)已經(jīng)超過合并后的first_name:will加上last_name:smith的分?jǐn)?shù)。

一種解決這些查詢類型的方法是簡單地索引first_namelast_namefields進(jìn)一個(gè)單一的full_namefield。當(dāng)然,這只能在索引過程中完成。

cross_field類型試著解決這些問題在查詢時(shí)刻,通過使用以term為中心的方法。它首先解析查詢string為單個(gè)的term,接著在任何field中查找每個(gè)term,就如同他們是在一個(gè)大的field進(jìn)行一樣。

如下的查詢:

{
  "multi_match" : {
    "query":      "Will Smith",
    "type":       "cross_fields",
    "fields":     [ "first_name", "last_name" ],
    "operator":   "and"
  }
}

被執(zhí)行為:

+(first_name:will last_name:will)
+(first_name:smith last_name:smith)

換句話說,所有term都必須放在至少一個(gè)field中以讓文檔匹配到。(與best_fields和most_fields進(jìn)行比較)

這解決了兩個(gè)問題中的一個(gè)。讓term frequencies的差異通過混合對(duì)所有field項(xiàng)的頻率來屏蔽差異完成。換句話說,first_name:smith將被看作它有與last_name:smith相同的權(quán)值。(事實(shí)上,first_name:smith比起last_name:smith有一點(diǎn)點(diǎn)優(yōu)勢,會(huì)讓結(jié)果的順序更加穩(wěn)定一些)

如果你通過調(diào)用Validate API運(yùn)行上述查詢,它將返回下面的解釋:

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

同樣的,它也會(huì)接受match query中介紹過的analyzer, boost, operator, minimum_should_match, zero_terms_query and cutoff_frequency

cross_field和analysis

cross_field類型可以僅對(duì)擁有相同的分析器的field在以term為中心的模式下進(jìn)行工作。擁有相同分析器的field常被像上面例子里那樣組合起來。
如果有多個(gè)群組(group),他們將被一個(gè)bool查詢包含起來。

例如,如果我們有一個(gè)firstlastfield,都有相同的分析器,加上一個(gè)first.edgelast.edge,兩者都使用edge_ngram分析器,這個(gè)查詢:

{
  "multi_match" : {
    "query":      "Jon",
    "type":       "cross_fields",
    "fields":     [
        "first", "first.edge",
        "last",  "last.edge"
    ]
  }
}

將被執(zhí)行為:

    blended("jon", fields: [first, last])
| (
    blended("j",   fields: [first.edge, last.edge])
    blended("jo",  fields: [first.edge, last.edge])
    blended("jon", fields: [first.edge, last.edge])
)

換句話說,firstlast可能會(huì)被組合起來作為一個(gè)單一的field,并且first.edgelast.edge也同樣被組合起來當(dāng)作一個(gè)單一的field。

擁有多個(gè)group很好,不過當(dāng)和operatorminimum_should_match組合時(shí),就可能會(huì)遇到most_fieldsbest_fields那樣的問題。

你可以輕易重寫這個(gè)查詢以兩個(gè)分開的cross_type查詢與一個(gè)bool查詢,然后應(yīng)用minimum_should_match參數(shù)到其中一個(gè)上面:

{
    "bool": {
        "should": [
            {
              "multi_match" : {
                "query":      "Will Smith",
                "type":       "cross_fields",
                "fields":     [ "first", "last" ],
                "minimum_should_match": "50%"  ..... 1
              }
            },
            {
              "multi_match" : {
                "query":      "Will Smith",
                "type":       "cross_fields",
                "fields":     [ "*.edge" ]
              }
            }
        ]
    }
}
  1. will或者smith肯定要出現(xiàn)在first或者lastfield中的一個(gè)中。

你可以強(qiáng)迫所有field在一個(gè)群組中,通過設(shè)置查詢中的analyzer參數(shù):

{
  "multi_match" : {
    "query":      "Jon",
    "type":       "cross_fields",
    "analyzer":   "standard",  ..... 1
    "fields":     [ "first", "last", "*.edge" ]
  }
}
  1. 對(duì)所有的field均使用standard分析器

這個(gè)查詢將按如下方式執(zhí)行:

blended("will",  fields: [first, first.edge, last.edge, last])
blended("smith", fields: [first, first.edge, last.edge, last])

tie_break

默認(rèn)情形,每個(gè)針對(duì)term的blened查詢將使用群組中任何field的最優(yōu)打分,然后這些分?jǐn)?shù)加在一起來給出最終的分?jǐn)?shù)。tie_breaker參數(shù)可以改變per-term查詢的默認(rèn)行為。它接受參數(shù):

  • 0.0 -first_name:willlast_name:will中選擇單一最優(yōu)分?jǐn)?shù)(默認(rèn))
  • 1.0 -將first_name:willlast_name:will的分?jǐn)?shù)相加
  • 0.0 < n < 1.0 -選出單一最優(yōu)分?jǐn)?shù)加上[tie_breaker乘上每個(gè)其他匹配field的分?jǐn)?shù)]

filters

exists filter

過濾其中特定field含有給定值的文檔。

geo bounding box filter

基于點(diǎn)位置來過濾在一個(gè)限定box中位置。假設(shè)有以下索引好的文檔:

{
    "pin" : {
        "location" : {
            "lat" : 40.12,
            "lon" : -71.34
        }
    }
}

那么下列簡單的查詢可以被一個(gè)geo_bounding_box過濾器執(zhí)行:

{
    "filtered" : {
        "query" : {
            "match_all" : {}
        },
        "filter" : {
            "geo_bounding_box" : {
                "pin.location" : {
                    "top_left" : {
                        "lat" : 40.73,
                        "lon" : -74.1
                    },
                    "bottom_right" : {
                        "lat" : 40.01,
                        "lon" : -71.12
                    }
                }
            }
        }
    }
}

lat,lon的類型

經(jīng)緯度作為屬性
{
    "filtered" : {
        "query" : {
            "match_all" : {}
        },
        "filter" : {
            "geo_bounding_box" : {
                "pin.location" : {
                    "top_left" : {
                        "lat" : 40.73,
                        "lon" : -74.1
                    },
                    "bottom_right" : {
                        "lat" : 40.01,
                        "lon" : -71.12
                    }
                }
            }
        }
    }
}
經(jīng)緯度作為數(shù)組
{
    "filtered" : {
        "query" : {
            "match_all" : {}
        },
        "filter" : {
            "geo_bounding_box" : {
                "pin.location" : {
                    "top_left" : [-74.1, 40.73],
                    "bottom_right" : [-71.12, 40.01]
                }
            }
        }
    }
}
經(jīng)緯度作為string
{
    "filtered" : {
        "query" : {
            "match_all" : {}
        },
        "filter" : {
            "geo_bounding_box" : {
                "pin.location" : {
                    "top_left" : "40.73, -74.1",
                    "bottom_right" : "40.01, -71.12"
                }
            }
        }
    }
}
地理信息hash
{
    "filtered" : {
        "query" : {
            "match_all" : {}
        },
        "filter" : {
            "geo_bounding_box" : {
                "pin.location" : {
                    "top_left" : "dr5r9ydj2y73",
                    "bottom_right" : "drj7teegpus6"
                }
            }
        }
    }
}

頂點(diǎn)(vertices)

除了以上的方法外還可以直接設(shè)置每個(gè)頂點(diǎn)的位置值

地理點(diǎn)類型

過濾器要求geo_point類型被設(shè)置在相關(guān)的field上

文檔中多個(gè)位置

過濾器可以與多個(gè)地理位置或者地點(diǎn)進(jìn)行工作。一旦一個(gè)單一點(diǎn)與過濾器匹配,文檔將被包含進(jìn)過濾器中。

類型(type)

The type of the bounding box execution by default is set to memory, which means in memory checks if the doc falls within the bounding box range.
約束的box的類型被默認(rèn)設(shè)置為memory。。。
某些時(shí)候,一個(gè)被索引過的選項(xiàng)執(zhí)行得更快速(但是注意geo_point類型肯定需要有被索引的lat和lon)。注意當(dāng)使用索引過的選項(xiàng)時(shí),文檔field中多個(gè)位置不被支持。

caching

過濾的結(jié)果默認(rèn)不被緩存。_cache可以被設(shè)為true來緩存過濾的結(jié)果。這相當(dāng)好用尤其時(shí)相同的bounding box參數(shù)被用于其他查詢的時(shí)候。注意,caching首次執(zhí)行的過程更高一些,因?yàn)樾枰獫M足不同的查詢。

geo distance filter

過濾哪些位于離一個(gè)給定geopoint的一個(gè)特定距離內(nèi)的文檔。假設(shè)有如下已經(jīng)索引的json:

{
    "pin" : {
        "location" : {
            "lat" : 40.12,
            "lon" : -71.34
        }
    }
}

那么下列簡單查詢可以執(zhí)行一個(gè)geo_distance過濾器:

{
    "filtered" : {
        "query" : {
            "match_all" : {}
        },
        "filter" : {
            "geo_distance" : {
                "distance" : "200km",
                "pin.location" : {
                    "lat" : 40,
                    "lon" : -70
                }
            }
        }
    }
}

可接受的格式

geo_point類型差不多

lat lon作為屬性
lat lon作為數(shù)組
lat lon作為string
geohash

選項(xiàng)

下列為filter可以使用的選項(xiàng)

  • distance 特定地點(diǎn)的半徑,落在此圓內(nèi)的點(diǎn)都被匹配。這個(gè)距離可以設(shè)置不同的單位。見距離單位
  • distance_type 如何計(jì)算距離,可選擇arc(精度最高)、sloppy_arc(快速,精度略少)和plane(最快)。默認(rèn)為sloppy_arc
  • optimize_bbox 是否在距離check之前使用首次執(zhí)行bound box check。默認(rèn)設(shè)置為memory將在內(nèi)存中進(jìn)行check。同樣也可以設(shè)置indexed從而使用索引后的值檢查(需要保證geo_point類型為index lat lon)

geo_point type

multi location per document

caching

geo distance range filter

Filters documents that exists within a range from a specific point:

{
    "filtered" : {
        "query" : {
            "match_all" : {}
        },
        "filter" : {
            "geo_distance_range" : {
                "from" : "200km",
                "to" : "400km"
                "pin.location" : {
                    "lat" : 40,
                    "lon" : -70
                }
            }
        }
    }
}

Supports the same point location parameter as the geo_distance filter. And also support the common parameters for range (lt, lte, gt, gte, from, to, include_upper and include_lower).

geoshape filter

has child filter

has_child過濾器接受一個(gè)查詢和child類型,來執(zhí)行過濾,得到的結(jié)果是包含了被匹配的child doc的父文檔。例如:

{
    "has_child" : {
        "type" : "blog_tag",
        "query" : {
            "term" : {
                "tag" : "something"
            }
        }
    }
}

has parent filter

has_parent過濾器接受查詢和一個(gè)父類型。查詢?cè)诟肝臋n空間執(zhí)行,這是由父類型確定的。過濾器返回子文檔這些文檔關(guān)聯(lián)的父文檔被命中。對(duì)于has_parent過濾器的剩下的選項(xiàng),其設(shè)置是于has_child過濾器一致。

filter example

{
    "has_parent" : {
        "parent_type" : "blog",
        "query" : {
            "term" : {
                "tag" : "something"
            }
        }
    }
}

這里parent_typefield名可以被簡寫為type。
filter實(shí)現(xiàn)的方式是首先運(yùn)行父查詢,然后進(jìn)行匹配到被匹配的每個(gè)文檔的子文檔。
has_parent過濾器也接受一個(gè)過濾器作為查詢的參數(shù)。

{
    "has_parent" : {
        "type" : "blog",
        "filter" : {
            "term" : {
                "text" : "bonsai three"
            }
        }
    }
}

內(nèi)存

為了支持父子的join(連接),所有父ID必須常駐內(nèi)存(在field數(shù)據(jù)緩存中)。另外,每個(gè)子文檔被映射到它的父文檔,使用一個(gè)long值(近似的)。建議保持string類型的父ID盡可能短來殲敵內(nèi)存的使用。
你可以使用indices statsnodesAPI來檢查有多少內(nèi)存已經(jīng)被ID緩存所占用,如:

curl -XGET "http://localhost:9200/_stats/id_cache?pretty&human"

caching

has_parent過濾器不能在filter cache中cache。_cache_cache_key選項(xiàng)在此filter中是no-op。同樣任何過濾器包含了has_parent,無論是直接還是間接,都不會(huì)被cache。

ids filter

過濾哪些僅有提供的id的文檔。注意,這個(gè)過濾器不要求_idfield被索引,因?yàn)樗恍枰褂?code>_uid就可以了。

{
    "ids" : {
        "type" : "my_type",
        "values" : ["1", "4", "100"]
    }
}

type
是可選的,也可以被省略,并且也能接受一個(gè)值的數(shù)組。

indices filter

indices過濾器可以在執(zhí)行多個(gè)indices時(shí)候使用,允許有一個(gè)過濾器執(zhí)行匹配一個(gè)特定的索引的list,另一個(gè)在一個(gè)索引上執(zhí)行匹配詞之外的索引。
當(dāng)然你可以使用indexfield來提供一個(gè)單一的index。
no_match_filter可以用none作為"string"的值(不匹配任何文檔),all(匹配所有)
filter是強(qiáng)制的,如同indices(或index

field的順序是重要的:如果indicesfilterno_match_filter之前出現(xiàn),那么關(guān)聯(lián)的過濾器只有在將要執(zhí)行的indices上進(jìn)行parse。沒有必要,避免潛在映射錯(cuò)誤。

script filter

可以定義腳本的過濾器,例如:

"filtered" : {
    "query" : {
        ...
    },
    "filter" : {
        "script" : {
            "script" : "doc['num1'].value > 1"
        }
    }
}

custom parameters

為了更快的執(zhí)行,腳本進(jìn)行編譯和緩存。如果相同的腳本被調(diào)用而只是參數(shù)的不同,那么建議使用可以傳遞參數(shù)的腳本。例如:

"filtered" : {
    "query" : {
        ...
    },
    "filter" : {
        "script" : {
            "script" : "doc['num1'].value > param1"
            "**params**" : {
                "param1" : 5
            }
        }
    }
}

caching

過濾器的結(jié)果默認(rèn)并不會(huì)被緩存,_cache可被設(shè)置為true來緩存過濾器的結(jié)果。當(dāng)我們要使用好多次相同的代碼時(shí)尤其好用。注意緩存的過程

mapping

映射時(shí)定義一個(gè)文檔該如何被映射到搜索引擎的過程,包含它可搜索的特征諸如哪些field可以搜索到,還有是否它們被tokenized。在ES中,一個(gè)索引可能存儲(chǔ)不同的“映射類型”。ES允許人們關(guān)聯(lián)多個(gè)mapping定義對(duì)每個(gè)mapping類型。
顯式的mapping定義在index/type層面。默認(rèn)對(duì)于定義一個(gè)顯式的mapping是沒有需求的,因?yàn)閙apping是自動(dòng)創(chuàng)建和注冊(cè),當(dāng)一個(gè)新的類型或者field被引入,而是mapping是有敏感的默認(rèn)設(shè)置的。僅當(dāng)默認(rèn)需要被重寫時(shí),mapping的定義才需要提供。

mapping types

mapping types時(shí)一種分割一個(gè)索引的文檔成邏輯組的方式。就把它當(dāng)成數(shù)據(jù)庫中的表吧。盡管type間有分割,這不是一種全分割(所有的最終更逗在同樣的Lucene索引下。)
type之間相同的名稱的field名強(qiáng)烈建議有 相同的type和相同的mapping特征(例如分析設(shè)置)。There is an effort to allow to explicitly "choose" which field to use by using type prefix (my_type.my_field), but it’s not complete, and there are places where it will never work (like faceting on the field).

然后在實(shí)際應(yīng)用中,這個(gè)要求幾乎不成為問題。field名經(jīng)常成為其typeness的暗示。(如first_name總是一個(gè)string)。注意,這個(gè)并不適用于交叉索引的情形。

mapping api

為了創(chuàng)建一個(gè)mapping,你需要Put Mapping API,或者你可以添加多個(gè)mapping當(dāng)你創(chuàng)建index時(shí)。

global settings

index.mapping.ignore_malformed全局設(shè)置可以設(shè)置在index層面來允許全局忽視malformed內(nèi)容(畸形的內(nèi)容例子是試著將一個(gè)文本string值所因?yàn)橐粋€(gè)數(shù)值類型。)
index.mapping.coerce全局設(shè)置可以被設(shè)置在index層來強(qiáng)迫所有的mapping類型數(shù)值內(nèi)容
(默認(rèn)設(shè)置為true并切coercion)

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

相關(guān)閱讀更多精彩內(nèi)容

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