ElasticSearch是一個基於Lucene的開源搜索引擎,支持全文檢索,提供restful接口。在ES中,提供了相似於MongoDB的面向文檔存儲服務,這種面向文檔的存儲很是靈活,可是文檔與文檔直接的關聯卻比較麻煩,MongoDB裏面有DBref,ElasticSearch裏面卻沒有這個,這篇文章就簡單講一講ES的關聯查詢。html
這種類型支持在一個文檔中嵌入多個另外類型的文檔。
假如說咱們須要在一個type裏面存儲多我的的名字,而且須要把姓和名分開存,這個時候咱們
能夠這樣去定義mapping:restful
{ "test" : { "properties" : { "users" : { "type" : "nested", "properties": { "first" : {"type": "string" }, "last" : {"type": "string" } } } } } }
首先把type定義成nested
類型,而後在users下面嵌入mapping的屬性。
對嵌入數據的查詢可使用「.
」進行訪問,具體內容能夠參考官網連接。app
使用內嵌的類型的優點在於一次查詢,自己的文檔和內嵌的文檔一塊兒返回。惟一不方便的就是對內嵌數據進行插入或者刪除操做的時候須要使用Update模塊,Update對數據的操做都是經過腳本實現的,我的感受使用起來不是很方便。爲了解決這個問題,咱們可使用新方法,parent-child
模塊。curl
這個模塊支持在插入數據的時候,能夠指定一條數據爲parent
,經過這種方式將2條數據關聯起來。
首先在定義mapping的時候就須要指定child
文檔須要關聯哪一個type的parent
,例如:elasticsearch
{ "user" : { "_parent": { "type": "test" }, "properties": { "first" : {"type": "string" }, "last" : {"type": "string" } } } }
user就是test的child
而後咱們須要在插入child
數據的時候指定他關聯的是具體哪一條parent
的id,假設咱們在test裏面有一條數據,id爲test_id,那麼咱們想插入一條child
數據關聯到id爲test_id的數據的時候,咱們須要這樣寫:ide
curl -XPUT localhost:9200/wahaha/user/user_id?parent=test_id -d ' { "first":"wang", "last":"ergou" }'
這裏咱們插入了一條id爲user_id的數據,而且和id爲test_id的數據關聯。
接下來咱們能夠經過child
的屬性去查找parent
:ui
{ "query": { "has_child": { "type": "user", "query": { "match":{ "last":"ergou" } } } } }
這裏咱們使用has_child
方法查找的和last等於二狗的user數據關聯的test數據,在has_child
方法中,咱們顯式指定了關聯的type爲user,而後對user進行了一次查詢,找到last等於二狗的數據,而後返回這條數據的parent
。
咱們還能夠經過parent
屬性去查找child
:搜索引擎
{ "query": { "has_parent": { "type": "test", "query": { "match":{ "name":"ergou`s father" } } } } }
這裏咱們使用的是has_parent
方法,和has_child
相似,咱們先找到二狗他爹這條數據,而後再找到這條數據的child
,返回結果。再提供一個官網連接
使用parent-child就比內嵌類型靈活不少,對數據的修改不須要使用Update。,能夠根據parent查child,也能夠根據child查parent,若是須要返回2種文檔就須要使用聚合。url