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_length和max_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_prefix與match_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
}
}
- 查詢?cè)~
- 查詢的域
fields和每個(gè)field的boosting
fields可以使用通配符(wildcards),如:
{
"multi_match" : {
"query" : "Will Smith",
"fields" : ["title", "*_name"] ..... 1
}
}
- 查詢
title、first_name和last_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_fields和type:most_fields代替。見multi_match查詢
默認(rèn),multi_match查詢對(duì)每個(gè)field均生成了一個(gè)match子句,接著將這些子句包含進(jìn)一個(gè)dis_max查詢。通過設(shè)置use_dis_max為false,他們將被包含進(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。參見phrase和phrase_prefix - phrase_prefix - 在每個(gè)field上運(yùn)行一個(gè)
match_phrase_prefix查詢并合并來自每個(gè)field的_score。參見phrase和phrase_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)解釋過了。
operator和minimum_should_match
這兩個(gè)類型是以field為中心的——他們對(duì)每個(gè)field產(chǎn)生一個(gè)match查詢。這是指operator和minimum_should_match參數(shù)被獨(dú)立地應(yīng)用在每個(gè)field上,這可能不是你本來想要的效果
例如:{ "multi_match" : { "query": "Will Smith", "type": "best_fields", "fields": [ "first_name", "last_name" ], "operator": "and" ..... 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
phrase和phrase_prefix類型和best_fields行為類似,但是他們使用了一個(gè)match_phrase或match_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_name和last_namefield“Will Smith”時(shí),best match可能會(huì)將“Will”放在一個(gè)field中,而把“Smith”放進(jìn)另一個(gè)。
這就如同
most_fields那樣,但是有兩個(gè)問題。一個(gè)問題是operator和minimum_should_match是按每field進(jìn)行的,而不是每個(gè)term。
第二個(gè)問題與相關(guān)性有關(guān)系:不同的term頻率在first_name和last_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_name和last_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è)first和lastfield,都有相同的分析器,加上一個(gè)first.edge和last.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])
)
換句話說,first和last可能會(huì)被組合起來作為一個(gè)單一的field,并且first.edge和last.edge也同樣被組合起來當(dāng)作一個(gè)單一的field。
擁有多個(gè)group很好,不過當(dāng)和operator或minimum_should_match組合時(shí),就可能會(huì)遇到most_fields和best_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" ]
}
}
]
}
}
- 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" ]
}
}
- 對(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:will和last_name:will中選擇單一最優(yōu)分?jǐn)?shù)(默認(rèn)) -
1.0-將first_name:will和last_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 stats和nodesAPI來檢查有多少內(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的順序是重要的:如果
indices在filter或no_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)