ES6.0以后,索引的type只能有一個,使得父子結構變的不那么清晰,畢竟對於java開發者來說,index->db,type->table的結構比較容易理解。
按照官方的說明,之前一個索引有多個type,如果有一個相同的字段在不同的type中出現,在ES底層其實是按照一個field來做lucene索引的,這很具有迷惑性,容易造成誤解。所以6.0以后,所有的字段都在索引的_doc【默認type】中集中定義。假設索引中會有parent和child兩個類型的文檔,那么可能parent引用了abcd字段,child引用了aef字段,各取所需。
目前我用的es版本為6.3,父子結構需要用join字段來定義,關系的映射用relations字段來指定。
一個索引中只能有一個join類型字段,如果定義一個以上的join字段,會報錯:Field [_parent_join] is defined twice in [_doc]
join字段中的relations集合,建好索引之后,可以增加映射,或者給原有的映射添加child,但是不能刪除原有的映射。
比如,原有的relations定義為:
"myJoin": { "type": "join", "eager_global_ordinals": true, "relations": { "parent_a": child_a1 } }
現在通過updateMapping API增加一條映射parent_b,原有的映射增加了child_a2和child_a3:
"myJoin": { "type": "join", "eager_global_ordinals": true, "relations": { "parent_a": [ "child_a1", "child_a2", "child_a3" ], "parent_b": "child_b" } }
中午睡了個午覺,接着再寫一點join的操作
- 根據子文檔查詢父文檔
GET /test_index_join/_search { "query": { "has_child": { "type": "child_a1", "score_mode": "max", # 基於child_a1文檔定義來搜索,query里的查詢字段是child_a1里的 "query": { "term": { "salesCount": 100 } } } } }
- 根據子文檔對父文檔進行排序
說明:根據子文檔的字段影響父文檔的的得分,然后父文檔根據_score來排序。
下面例子中,父文檔的得分為:_score * child_a1.salesCount,score_mode可以是min,max,sum,avg,first等。
GET /test_index_join/_search { "query": { "has_child": { "type": "child_a1", "score_mode": "max", "query": { "function_score": { "script_score": { "script": "_score * doc['salesCount'].value" } } } } }, "sort": [ { "_score": { "order": "asc" } } ] }
還可以依賴field_value_factor來影響父文檔得分,效果相似,效率更高;functions支持多個field影響因子,多個因子的默認[score_mode]計分模式為multiply[相乘],還有其他可選模式為:min,max,avg,sum,first,multiply。
下面例子中,父文檔的得分為:salesCount,因為沒有其他的影響因子,如果有多個,則取最大的一個,因為score_mode為max。
GET /test_index_join/_search { "query": { "has_child": { "type": "child_a1", "score_mode": "max", "query": { "function_score": { "functions": [ { "field_value_factor": { "field": "salesCount" } } ] } } } }, "sort": [ { "_score": { "order": "asc" } } ] }
- 根據父文檔查詢子文檔
GET /test_index_join/_search { "query": { "has_parent": { "parent_type": "parnet_a", # 基於parnet_a來搜索,query里的查詢字段是parnet_a里的 "query": { "range": { "price": { "gt": 1, "lte": 200 } } } } } }