編程隨筆-ElasticSearch知識導圖(4):搜索

1. 原理

??全文搜索是ES的核心功能伍茄。ES中的數(shù)據(jù)按數(shù)據(jù)特性可分為兩類:確切值及全文文本绳瘟。ES中如keyword,date這些類型的值都可視為確切值苛茂。而text類型的值則視為全文文本數(shù)據(jù)缤骨。
??為了對全文文本進行搜索寞忿,ES使用分析器(analyzer,根據(jù)不同自然語言际邻、不同要求選擇不同的分析器)將文本分析為單獨的詞(英文為terms或tokens,這里符合中國人的習慣芍阎,稱為詞),然后根據(jù)分詞結(jié)果創(chuàng)建倒排索引(inverted index)世曾。倒排索引以文本中的詞為鍵,該詞在文檔中出現(xiàn)位置為值的一個數(shù)據(jù)結(jié)構(gòu),不同于常見的以文檔序號(或標題)為鍵谴咸,文檔內(nèi)容為值的索引形式轮听,所以稱為倒排索引。ES中文檔對象是一個結(jié)構(gòu)化的JSON數(shù)據(jù)對象岭佳,每一個JSON文檔中被索引的字段都有自己的倒排索引血巍,全文搜索即在倒排索引中搜索。
??ES中珊随,分布式搜索操作需要分散到所有相關(guān)的分片中述寡,然后收集所有的結(jié)果。對于一個搜索請求叶洞,搜索結(jié)果在不同分片中的分布密度可能是不同的鲫凶,有可能出現(xiàn)一個分片包括了90%的記錄,而其它分片卻只包含極少記錄的情況衩辟。當需要對搜索結(jié)果排序時螟炫,也需要從各獨立的分片中收集到所有的搜索結(jié)果后再統(tǒng)一進行排序,這個過程類似于map-reduce的混洗(shuffle)過程艺晴。對于大數(shù)據(jù)集昼钻,這個過程可能會非常昂貴掸屡。因而在創(chuàng)建數(shù)據(jù)模型和設(shè)計搜索指令時我們應考慮搜索效率。
??ES將搜索請求執(zhí)行分為兩階段:在第一階段查詢(query)階段然评,每個涉及搜索的分片執(zhí)行搜索請求仅财,獲取本地搜索記錄的排序后列表,并把這些可供協(xié)調(diào)節(jié)點(coordinating node)進行全局排序等操作的元數(shù)據(jù)信息返回給協(xié)調(diào)節(jié)點沾瓦。在第二階段取回(fetch)階段满着,協(xié)調(diào)節(jié)點僅向包含搜索結(jié)果的分片請求具體的文檔對象返回給用戶。

2. 搜索API

??ES提供了強大的數(shù)據(jù)搜索能力贯莺,在API級別提供基于URI和基于請求消息體兩種搜索操作方式风喇。

2.1. 基于URI的搜索

2.1.1. 基本格式

??基于URI的搜索使用一個HTTP的GET請求攜帶搜索請求參數(shù)。搜索參數(shù)為(key,value)形式的名值對缕探,以”&”連接魂莫。如果搜索請求中不帶搜索參數(shù)則表示搜索所有記錄。
??仍以《編程隨筆-ElasticSearch知識導圖(3):映射》中第2節(jié)中的銀行賬號索引為例爹耗,先來看一個使用URI的搜索請求:

curl -iXGET 'localhost:9200/bank/_search?pretty&q=(firstname:Amber)AND(lastname:Duke)'

??上面的請求中URI中為索引名(bank)后攜帶搜索路徑(_search)耙考,并在URI的“?”之后的查詢字符串中攜帶查詢參數(shù)q潭兽,查詢滿足firstname為Amber且lastname為Duke'的記錄(若要實現(xiàn)全文搜索倦始,則不需要添加前面的域名),查詢參數(shù)q在子查詢表達式前(格式為”域名:值”)使用“+”表示應滿足該條件山卦, “-”表示不應滿足該條件鞋邑。q中子查詢表達式使用”AND”或“OR”表示條件之間的邏輯與或關(guān)系。

2.1.2. 通配符與正則表達式

??查詢字符串支持“账蓉?”和“*”這樣的簡單通配符枚碗,上面的查詢示例使用統(tǒng)配符之后可以變?yōu)槿缦滦问剑?/p>

curl -iXGET 'localhost:9200/bank/_search?pretty&q=(f\*name:A?ber)AND(lastname:Duke)'

查詢條件字符串支持正則表達式(使用”/”包含起來),上面的查詢可表達為如下形式:

curl -iXGET 'localhost:9200/bank/_search?pretty&q=(firstname:/A~r/)AND(lastname:Duke)'

2.1.3. 分頁與排序

??ES默認在一次搜索請求中只返回搜索結(jié)果的前10條記錄铸本。因而當搜索記錄較多時肮雨,搜索結(jié)果需要進行分頁。
??ES提供搜索參數(shù)“from”和“size”用于指示返回結(jié)果開始的索引值與返回的數(shù)目箱玷。由于分頁的結(jié)果往往基于記錄的排序結(jié)果怨规,因而使用“sort”參數(shù)實現(xiàn)搜索結(jié)果的排序。
??考慮如下查詢:

curl -iXGET 'localhost:9200/bank/_search?pretty&q=(balance:>5000)&sort=balance:desc&from=0&size=3'

??查詢余額(balance)大于5000的人群中最有錢的前三位汪茧。
??如果不想搜索出所有字段椅亚,可以在搜索條件中使用” _source”參數(shù)指定在返回結(jié)果中指定的域。上面的搜索請求可轉(zhuǎn)換為如下請求:

curl -iXGET 'localhost:9200/bank/_search?pretty&q=(balance:>5000)&sort=balance:desc&from=0&size=3&_source=balance,firstname,lastname'

??在返回的搜索結(jié)果中可以看到“_source”對象中只有“balance,firstname,lastname”這三個字段舱污。
??現(xiàn)在我們發(fā)現(xiàn)基于URI的搜索格式已經(jīng)非常類似于常用的SQL格式了呀舔。的確,ES支持SQL語言的查詢(在xpack插件中支持)。

2.1.4. 搜索參數(shù)

??簡單列舉一下常用的基于URI搜索的參數(shù):

參數(shù) 描述
q 查詢條件字符串
df 查詢的缺省域
analyzer 分析查詢字符串時使用的分析器
analyze_wildcard 是否分析通配符
default_operator 確定缺省邏輯關(guān)系是AND或OR,缺省是OR.
explain 在結(jié)果中包含對于命中記錄得分的解釋
_source 選擇在結(jié)果中展示的字段
sort 排序條件
timeout 搜索超時時間
terminate_after 每個分片上采集的最大搜索記錄數(shù)目
from 搜索結(jié)果起始索引
size 本次搜索結(jié)果的最大數(shù)目
search_type 可以取值:dfs_query_then_fetch 或 query_then_fetch. 缺省為query_then_fetch

??參數(shù)中的search_type用來定義不同的搜索類型來應對不同場景媚赖,其取值可為:

  • query_then_fetch:將搜索分為query和fetch兩個階段霜瘪,如前面的銀行賬戶查詢例子,與搜索條件相關(guān)的所有分片在第一階段返回給協(xié)調(diào)節(jié)點余額大于5000的記錄元數(shù)據(jù)信息惧磺,協(xié)調(diào)節(jié)點排序后颖对,發(fā)現(xiàn)余額最大的前3名都在1個分片中,那么第二階段它只需向包含前3名的分片請求完整的搜索結(jié)果數(shù)據(jù)磨隘。
  • dfs_query_then_fetch:dfs是 Distributed Frequency Search的簡寫缤底。與query_then_fetch方式基本相同,只是增加了一個從所有相關(guān)分片中獲取詞頻(本地IDF)以便計算全局詞頻(全局IDF)的預查詢階段番捂,用于更精確的相關(guān)性評分(scoring)計算(文獻2中不建議在生產(chǎn)環(huán)境下使用此選項)个唧。

2.2. 基于請求消息體的搜索

2.2.1. 何為DSL

??DSL(Domain Specific Language)旨在向目標用戶提供人性化的界面,其要旨在于溝通设预。DSL擁有貼近用戶思維的語法結(jié)構(gòu)徙歼,這些語言抽象依賴于背后提供支撐的語義模型。
??ES中定義用于搜索的DSL使用JSON格式,是一種外部DSL語言。
??使用URI表示的搜索示例使用DLS改寫后的形式如下:

curl -iXPOST 'localhost:9200/bank/_search?pretty'  -H 'Content-Type: application/json' -d'
{ 
    "query": {
        "bool": {
            "must": {
                "match_all": {}
            },
            "filter": {
                "range": {
                    "balance": {
                        "gte": 5000
                    }
                }
            }
        }
    },
    "sort": {
        "balance": {
            "order": "desc"
        }
    },
    "from": 0,
    "size": 3,
    "_source": ["balance","firstname","lastname"]
}
'

??上例中將請求消息體分為兩個部分沽讹,“query”子句和其它搜索參數(shù)元素,“query”子句使用Query DSL描述酿秸。其它搜索參數(shù)同2.1.4節(jié)中描述的參數(shù)。
??搜索DSL提供更加豐富的搜索參數(shù)與功能魏烫,更多內(nèi)容參見文獻1允扇。

2.2.2. Query DSL

??搜索請求中query子句可應用于查詢上下文(Query context)和/或過濾上下文(Filter context)中。查詢上下文中query子句用來回答文檔對象的匹配程度(計算score值衡量相關(guān)性)则奥,過濾上下文中query子句用來回答文檔對象是否符合過濾條件,只有是否兩個選擇狭园。簡單來說读处,需要全文搜索或不精確匹配(考察相關(guān)性)時應用查詢上下文,需要精確過濾時應用過濾上下文唱矛。
??上節(jié)的搜索示例既應用于查詢上下文又應用于過濾上下文中罚舱, “must”子句指示了查詢條件(示例中沒有設(shè)置查詢條件,其實可以省略)绎谦;“filter”子句指示了過濾條件管闷。
??將示例中的“match_all”換上更具體的查詢條件,查找姓“Barry”的最有錢的前三位同學:

curl -iXPOST 'localhost:9200/bank/_search?pretty'  -H 'Content-Type: application/json' -d'
{
  "query": {
        "bool": {
            "must": {
                "match": {"lastname":"Barry"}
            },
            "filter": {
                "range": {
                    "balance": {
                        "gte": 5000
                    }
                }
            }
        }
    },
    "sort": {
        "balance": {
            "order": "desc"
        }
    },
    "from": 0,
    "size": 3,
    "_source": ["balance","firstname","lastname"]
}
'

??上例在查詢子句中指定了域名為“l(fā)astname”窃肠,該域表示一個確切值包个,不需要全文搜索。因而將match子句轉(zhuǎn)換為term子句冤留,放到"filter"子句中碧囊,搜索出的結(jié)果一樣:

curl -iXPOST 'localhost:9200/bank/_search?pretty'  -H 'Content-Type: application/json' -d'
{
    "query": {
        "bool": {
            "filter": [
                {
                    "term": {
                        "lastname.keyword": "Barry"
                    }
                },
                {
                    "range": {
                        "balance": {
                            "gte": 5000
                        }
                    }
                }
            ]
        }
    },
    "sort": {
        "balance": {
            "order": "desc"
        }
    },
    "from": 0,
    "size": 3,
    "_source": [
        "balance",
        "firstname",
        "lastname"
    ]
}
'

??match和term子句常用來組建查詢子句: term用于搜索域的確切值树灶,即term指示的值在搜索時不經(jīng)過分析器的處理,對于text類型的域糯而,term子句訪問的分析器產(chǎn)生的倒排索引天通,常常無法獲得精確匹配的搜索結(jié)果(如term搜索值中有大寫字母但不經(jīng)過分析器轉(zhuǎn)換,而待搜索的文本域在經(jīng)分析器分析后倒排索引中都變?yōu)樾懽址ㄍ眨瑒t無法精確匹配)像寒。term常用于搜索keyword、date瓜贾、數(shù)字這些具有確切值類型的域(上面示例中使用的是lastname.keyword這個域)诺祸,而對需要全文搜索的域的常使用match子句(搜索值與文本域都經(jīng)分析器轉(zhuǎn)換過,保持一致)阐虚。term子句搜索時不對搜索結(jié)果評分(score)序臂,因此效率要高。
??實際應用 中实束,如果不涉及全文搜索需求奥秆,可在過濾上下文中使用term子句。match和term子句還衍生出諸多變化(如match_phrase咸灿,match_phrase_prefix构订,multi_match,terms,),這些衍生的語法可參考文獻1避矢。
??搜索語句中通常會使用多個match或term子句構(gòu)建組合查詢悼瘾,ES提供must,should, must_not等邏輯運算符來組合一個復雜查詢,構(gòu)成一個布爾表達式审胸。Query DSL可使用如下格式表示一個布爾表達式:

{
    "query": {
        "bool": {
            "must": [],
            "must_not":[],
            "should":[],
            "filter":[]
        }
    }
}

??bool子句為真需要滿足bool子句中各子句的查詢條件亥宿。must、should砂沛、must_not烫扼、filter子句均可為數(shù)組格式(只有一個子元素時可以寫為對象格式),數(shù)組中每個子對象可為match或term子句碍庵。其中:must約束子元素之間的邏輯與(AND)關(guān)系映企,should約束子元素之間的邏輯或(OR)關(guān)系,must_not約束各子元素的邏輯非(NOT)關(guān)系静浴。bool子句之間是可以嵌套的堰氓,一個bool子句可做為另一個bool子句的子條件,以構(gòu)建更復雜層次的查詢苹享。
??將上面的搜索條件增加一個子條件双絮,查找姓“Barry”或名為“Burton”的最有錢的前三位同學,查詢命令為如下形式:

curl -iXPOST 'localhost:9200/bank/_search?pretty'  -H 'Content-Type: application/json' -d'
{
    "query": {
        "bool": {
            "filter": [
                {
                    "bool": {
                        "should": [
                            {
                                "term": {
                                    "lastname.keyword": "Barry"
                                }
                            },
                            {
                                "term": {
                                    "firstname.keyword": "Burton"
                                }
                            }
                        ]
                    }
                },
                {
                    "range": {
                        "balance": {
                            "gte": 5000
                        }
                    }
                }
            ]
        }
    },
    "sort": {
        "balance": {
            "order": "desc"
        }
    },
    "from": 0,
    "size": 3,
    "_source": [
        "balance",
        "firstname",
        "lastname"
    ]
}
'

??Query DSL中對于通配符和正則表達式使用專用的子句“wildcard”和“regexp”,與基于URI的搜索方式有些區(qū)別掷邦,請大家注意白胀。
??Query DSL比較強大,語法也多抚岗。我的意見是:不用一次就全部弄清楚全部的子句語法或杠,需要時再去文獻1查一下即可;使用本節(jié)的bool子句格式能夠解決80%以上的問題宣蔚;查詢子句的層次越少越好向抢,因為能提高效率;對于確切值的查詢條件盡量放到filter子句中胚委。
??本節(jié)最后使用一張圖總結(jié)一下Query DSL的常用語法:


Query DSL

2.2.3. 搜索模板

??ES的搜索API支持使用mustache語言渲染的搜索模板挟鸠,上節(jié)的搜索示例可以改寫成如下模板形式:

curl -iXPOST 'localhost:9200/bank/_search/template?pretty'  -H 'Content-Type: application/json' -d'
{
    "source": {
        "query": {
            "bool": {
                "must": {
                    "match_all": {}
                },
                "filter": {
                    "range": {
                        "{{field_1}}": {
                            "gte": "{{_base}}"
                        }
                    }
                }
            }
        },
        "sort": {
            "{{field_1}}": {
                "order": "desc"
            }
        },
        "from": 0,
        "size": 3,
        "_source": [
            "{{field_1}}",
            "{{field_2}}",
            "{{field_3}}"
        ]
    },
    "params": {
        "_base": 5000,
        "field_1":"balance",
        "field_2":"firstname",
        "field_3":"lastname"
    }
}
'

??在使用模板的搜索中,URI變?yōu)椤癬search/template”亩冬,模板使用“source”子句描述艘希,模板的變參使用“{{}}”來標識,實參在“params”被定義硅急。
??實際使用中覆享,使用的模板的好處在于我們只需為相同模式的查詢定義一次即可,運行時只需賦值對應的實參即可营袜。設(shè)計應用系統(tǒng)時利用預置的搜索模板可以提升開發(fā)效率撒顿,對于需要二次開發(fā)的系統(tǒng)而言模板也對外則屏蔽了實現(xiàn)細節(jié)。

2.2.4. 嵌套對象搜索

??考慮對域“fullname”的映射:

"fullname": {
    "properties": {
        "age": {
            "type": "long"
        },
        "firstname": {
            "type": "text",
            "fields": {
                "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                }
            }
        },
        "lastname": {
            "type": "text",
            "fields": {
                "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                }
            }
        }
    }
}

??要在該索引中搜索名為“zhang”的記錄荚板,可寫為如下簡單的查詢語句:

{
    "_source": [
        "fullname"
    ],
    "query": {
        "match": {
            "fullname.firstname": "zhang"
        }
    }
}

??其中用于匹配的字段“firstname”凤壁,使用“.”表示法來表明該屬性屬于“fullname”這個對象,而并非索引中的頂層域跪另。
??對于未顯式在映射中定義嵌套子對象的屬性拧抖,只以“nested”類型定義的子對象,在查詢中需要使用“nested”子句查詢免绿,將“fullname”的映射修改未如下形式:

{
    "fullname": {
        "type": "nested"
    }
}

??上面的查詢語句可改寫為如下形式:

{
    "_source": [
        "fullname"
    ],
    "query": {
        "nested": {
            "path": "fullname",
            "query": {
                "match": {
                    "fullname.firstname": "zhang"
                }
            }
        }
    }
}

3. 關(guān)聯(lián)查詢

??真實世界中數(shù)據(jù)之間的關(guān)系總是如此復雜徙鱼。
??關(guān)系數(shù)據(jù)庫提供多表聯(lián)合(join)查詢,使用鍵來關(guān)聯(lián)表之間的關(guān)系针姿。如同其它Nosql數(shù)據(jù)庫一樣,ES建議在數(shù)據(jù)建模時扁平化厌衙,使得一個領(lǐng)域本體中的數(shù)據(jù)關(guān)系“內(nèi)聚”在一個索引中距淫。
??在ES中對一個集群的多個索引進行搜索非常方便,在請求URI中填寫需要參與搜索的索引即可婶希,如“l(fā)ocalhost:9200/_search?pretty”表示搜索集群中所有索引榕暇。而對多個域進行同一條件搜索,Query DSL也提供了“multi_match”這樣的子句。
??ES中對于相同的域名在搜索時不區(qū)分其屬于哪個索引彤枢,因此并不能直接支持關(guān)系數(shù)據(jù)庫中“table1.field1=table2.field1”這樣的索引間(相當于表間)關(guān)聯(lián)查詢狰晚,文獻2中討論了四種管理關(guān)聯(lián)數(shù)據(jù)的方式:
??1. 在應用層模擬關(guān)系數(shù)據(jù)庫連接:這種方法實際是將關(guān)系數(shù)據(jù)庫的一次接連查詢操作分解為兩次查詢操作,要求關(guān)聯(lián)的兩個索引的數(shù)據(jù)對象之間保存關(guān)聯(lián)的外鍵缴啡。假設(shè)有索引index1包含{id11壁晒,field11,field12}屬性,index2包含{id21业栅,field21,field2秒咐,id11}屬性, id11為index2的外鍵碘裕,對于涉及index1和index2的應用級查詢携取,將其分解為兩次查詢:第一次根據(jù)查詢條件中index1的字段查詢出符合條件的id11,第二次根據(jù)第一次查詢出的id11值及查詢條件中index2的字段查詢出符合條件記錄帮孔。
??2. 增加冗余副本數(shù)據(jù):在一個索引中增加需要關(guān)聯(lián)的另一個索引的數(shù)據(jù)雷滋,這樣增加了第一個索引的冗余數(shù)據(jù),使得關(guān)聯(lián)查詢只在第一個索引中進行文兢。
??3. 使用嵌套對象來保存關(guān)聯(lián)關(guān)系:這種方式的思路是從領(lǐng)域頂層建模晤斩,將需要關(guān)聯(lián)的原本獨立的領(lǐng)域本體合并為一個總的本體,然后根據(jù)這個總的本體來建立映射禽作。原來獨立的領(lǐng)域本體對應的數(shù)據(jù)對象在總的數(shù)據(jù)對象中成為了嵌套的子對象尸昧。
??4. 在對象之間建立父子關(guān)聯(lián)關(guān)系:還記得我們在《編程隨筆-ElasticSearch知識導圖(3):映射》一文中提到,ES中可以設(shè)置文檔對象之間為父子關(guān)系的內(nèi)容嗎旷偿?建立數(shù)據(jù)對象之間的父子關(guān)系本質(zhì)上是建立一顆對象層次樹烹俗,將對象之間的關(guān)聯(lián)關(guān)系轉(zhuǎn)換為樹上節(jié)點間的父子(祖先)關(guān)系。Query DSL中提供了has_child萍程、has_parent幢妄、parent_id這樣的查詢子句。
??綜上所述茫负,在ES實現(xiàn)關(guān)聯(lián)查詢本質(zhì)上使用的方式無外乎兩種:

  1. 把所有數(shù)據(jù)都建模到一個索引中(6.0版本后一個索引中只有一個類型(type)),上面講到的后三種方式都基于這個思路;
  2. 數(shù)據(jù)對象分布在多個索引中蕉鸳,但對象間有字段進行關(guān)聯(lián),通過將聯(lián)合查詢分解為多個分步查詢(只查詢一個索引)得到最終結(jié)果忍法。
    ??似乎在ES中無法再現(xiàn)關(guān)系數(shù)據(jù)庫強大的關(guān)聯(lián)查詢潮尝,但請注意,在關(guān)系數(shù)據(jù)庫中執(zhí)行多表的join操作也是非常低效的饿序。根據(jù)應用需求勉失,可以在ES中設(shè)計合理的數(shù)據(jù)模型去盡量滿足關(guān)聯(lián)查詢。

4. 一個設(shè)計實例

4.1. GA/T 1400.3的查詢指令

??在《編程隨筆-ElasticSearch知識導圖(3):映射》一文中原探,介紹了遵循GA/T 1400.3的視頻圖像信息數(shù)據(jù)庫(以下簡稱視圖庫)的數(shù)據(jù)模型乱凿,并示例定義了視圖庫中索引的映射顽素。
??視圖庫中各索引對應GA/T 1400.3定義的各數(shù)據(jù)對象類型,視圖庫的數(shù)據(jù)模型是一個扁平的數(shù)據(jù)模型徒蟆。不同類型的對象之間具有關(guān)聯(lián)關(guān)系胁出,通過對象中的外鍵字段進行關(guān)聯(lián)。如人段审、車全蝶、物對象的來源標識字段與圖像對象的圖像標識關(guān)聯(lián)。
??視圖庫提供的數(shù)據(jù)服務(wù)接口完成對視圖庫的查詢功能戚哎,視圖庫的查詢接口是標準的restful風格的GET接口裸诽。每個查詢接口對應一個數(shù)據(jù)對象類型(使用資源URI指示數(shù)據(jù)對象類型),使用查詢字符串指示查詢條件型凳。GA/T 1400.3提供的一個查詢指令示例如下:

//查找身高在1.60m~1.70m 之間丈冬,攜帶紅色包的人員記錄,返回結(jié)果按年齡上限排序甘畅,且只返回PersonID埂蕊、SourceID兩個屬性。
GET /VIID/Persons?((Person.HeightUpLimit <=170) AND (Person.HeightLowerLimit >=160))&(Person.BagColor=Red)&(Sort = Person.AgeUpLimit)& (Fields= (PersonID疏唾,SourceID))

??GA/T 1400.3的附錄F中定義了視圖庫的查詢指令規(guī)范蓄氧,主要參照了SQL語言規(guī)范:定義了算術(shù)運算符、邏輯運算符槐脏、比較運算符喉童、聚合函數(shù)及分頁參數(shù)等。除了算術(shù)運算符在ES中不支持之外顿天,其它的規(guī)范要求都可在ES的DSL中找到對應語法(注:根據(jù)視圖庫的對象類型定義堂氯,實際應用中在查詢時基本不會有需要進行加減乘除計算的字段,但如果一定要保證規(guī)范的完整性牌废,需要考慮一些變通手段)咽白。
??如果在基于視圖庫中的應用系統(tǒng)中需要涉及到關(guān)聯(lián)查詢,可以使用上節(jié)提到的在應用層分步查詢的方法鸟缕。

4.2. 將查詢指令轉(zhuǎn)換為搜索API

??分析一下視圖庫查詢字符串的特點:查詢字符串由多個子查詢條件組成晶框,每個子查詢條件使用“&”連接(為邏輯與關(guān)系),子查詢條件可分為三類:
??1. 針對對象域的布爾表達式懂从,該表達式可為復合邏輯表達式授段。
??2.返回結(jié)果字段表達式(使用“Fields”關(guān)鍵字),指示出現(xiàn)在查詢結(jié)果中的返回字段番甩,這些字段中可能會有聚合函數(shù)(如最大畴蒲、最小值)。
??3.分頁排序表達式对室,指示分頁記錄和位置及排序方式等模燥,使用Sort,PageRecordNum,RecordStartNo,MaxNumRecordReturn等關(guān)鍵字。
??可在視圖庫中編寫一個查詢指令轉(zhuǎn)換器掩宜,解析查詢字符串中的各子查詢條件蔫骂,并將這些子查詢條件組合為ES支持的查詢URI或查詢消息體。
??上節(jié)中提到的查詢指令示例牺汤,轉(zhuǎn)換為URI后的查詢格式如下:

curl -iXGET 'localhost:9200/person/_search?pretty&q=((PersonObject.HeightUpLimit:<=170)AND(PersonObject.HeightLowerLimit:>=160))AND(PersonObject.BagColor:4)&sort=PersonObject.AgeUpLimit:asc&_source=PersonObject.PersonID辽旋,PersonObject.SourceID'

??轉(zhuǎn)換為DSL描述的消息體如下:

{
    "query": {
        "bool": {
            "filter": [
                {
                    "bool": {
                        "must": [
                            {
                                "range": {
                                    "PersonObject.HeightUpLimit": {
                                        "lte": 170
                                    }
                                }
                            },
                            {
                                "range": {
                                    "PersonObject.HeightLowerLimit": {
                                        "gte": 160
                                    }
                                }
                            }
                        ]
                    }
                },
                {
                    "term": {
                        "PersonObject.BagColor": "4"
                    }
                }
            ]
        }
    },
    "sort": {
        " PersonObject.AgeUpLimit": {
            "order": "asc"
        }
    },
    "_source": [
        "PersonObject.PersonID",
        "PersonObject.SourceID"
    ]
}

5. 參考文獻

  1. https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
  2. Clinton Gormley &Zachary Tong, Elasticsearch: The Definitive Guide,2015
  3. Debasish Ghosh,DSLs in action, 2013
  4. GA/T 1400.3 公安視頻圖像信息應用系統(tǒng) 第3部分:數(shù)據(jù)庫技術(shù)要求檐迟,2017

本系列文章:

編程隨筆-ElasticSearch知識導圖(1):全景
編程隨筆-ElasticSearch知識導圖(2):分布式架構(gòu)
編程隨筆-ElasticSearch知識導圖(3):映射
編程隨筆-ElasticSearch知識導圖(4):搜索
編程隨筆-ElasticSearch知識導圖(5):聚合
編程隨筆-ElasticSearch知識導圖(6):管理

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末补胚,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子追迟,更是在濱河造成了極大的恐慌溶其,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件敦间,死亡現(xiàn)場離奇詭異瓶逃,居然都是意外死亡,警方通過查閱死者的電腦和手機廓块,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門厢绝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人带猴,你說我怎么就攤上這事昔汉。” “怎么了拴清?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵靶病,是天一觀的道長。 經(jīng)常有香客問我贷掖,道長嫡秕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任苹威,我火速辦了婚禮昆咽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘牙甫。我一直安慰自己掷酗,他們只是感情好,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布窟哺。 她就那樣靜靜地躺著泻轰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪且轨。 梳的紋絲不亂的頭發(fā)上浮声,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天虚婿,我揣著相機與錄音,去河邊找鬼泳挥。 笑死然痊,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的屉符。 我是一名探鬼主播剧浸,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼矗钟!你這毒婦竟也來了唆香?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤吨艇,失蹤者是張志新(化名)和其女友劉穎躬它,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秸应,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡虑凛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了软啼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片桑谍。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖祸挪,靈堂內(nèi)的尸體忽然破棺而出锣披,到底是詐尸還是另有隱情,我是刑警寧澤贿条,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布雹仿,位于F島的核電站,受9級特大地震影響整以,放射性物質(zhì)發(fā)生泄漏胧辽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一公黑、第九天 我趴在偏房一處隱蔽的房頂上張望邑商。 院中可真熱鬧,春花似錦凡蚜、人聲如沸人断。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽恶迈。三九已至,卻和暖如春谱醇,著一層夾襖步出監(jiān)牢的瞬間暇仲,已是汗流浹背步做。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留奈附,地道東北人辆床。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像桅狠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子轿秧,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

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