如何在Elasticsearch中通过ID关联STAT GROUP与STAT DATA文档?
嘿,我来帮你解决这个关联需求!根据你的文档结构,要把STAT GROUP里statValues._ref和STAT DATA的_id关联起来,有几种实用的实现方式,我给你一步步拆解清楚:
方案一:用Join类型建立父子文档关系
这是Elasticsearch官方推荐的处理独立文档关联的方案,适合你需要分开维护两类文档,但又要随时查询它们关联关系的场景。
第一步:创建带Join字段的索引
首先得建一个索引,用Join字段定义stat_group(父文档,对应你的STAT GROUP)和stat_data(子文档,对应STAT DATA)的关系:
PUT /stat_index { "mappings": { "properties": { "relation": { "type": "join", "relations": { "stat_group": "stat_data" } }, "statValues": { "type": "nested", "properties": { "_ref": { "type": "keyword" } } }, "key": { "type": "keyword" } } } }
这里把statValues设为nested类型,因为它是数组对象,确保后续能正确处理每个元素的关联。
第二步:插入父文档(STAT GROUP)
直接插入你的STAT GROUP数据,指定它的关系类型是stat_group:
PUT /stat_index/_doc/38282922829 { "relation": "stat_group", "statValues": [ { "_ref": "282828290" } ] }
第三步:插入子文档(STAT DATA)
插入子文档时,要指定它的父文档ID,并且路由和父文档一致(保证父子文档存在同一个分片上,查询更高效):
PUT /stat_index/_doc/282828290?routing=38282922829 { "relation": { "name": "stat_data", "parent": "38282922829" }, "key": "itemsGained" }
第四步:查询关联数据
如果要查某个STAT GROUP对应的所有STAT DATA,用has_child查询,配合inner_hits返回子文档详情:
GET /stat_index/_search { "query": { "has_child": { "type": "stat_data", "query": { "match_all": {} }, "inner_hits": {} } } }
反过来,要查某个STAT DATA对应的父STAT GROUP,就用has_parent查询:
GET /stat_index/_search { "query": { "has_parent": { "parent_type": "stat_group", "query": { "match_all": {} }, "inner_hits": {} } } }
方案二:用Terms查询+批量获取(适合简单关联)
如果你的STAT DATA不怎么变动,或者只是偶尔需要关联查询,可以用这种轻量方式:
第一步:分别创建索引
比如建两个独立索引:stat_group_index存STAT GROUP,stat_data_index存STAT DATA。
第二步:插入数据
先存STAT DATA:
PUT /stat_data_index/_doc/282828290 { "key": "itemsGained" }
再存STAT GROUP:
PUT /stat_group_index/_doc/38282922829 { "statValues": [ { "_ref": "282828290" } ] }
第三步:关联查询
先查STAT GROUP拿到所有_ref值:
GET /stat_group_index/_search { "query": { "match_all": {} }, "_source": "statValues._ref" }
然后用_mget批量获取对应的STAT DATA:
GET /stat_data_index/_mget { "ids": ["282828290"] }
如果想更高效,还可以用Enrich Policy把STAT DATA的字段提前同步到STAT GROUP里,之后查询就不用再关联了:
# 创建Enrich策略,指定关联字段和要同步的字段 PUT /_enrich/policy/stat_data_policy { "match": { "indices": "stat_data_index", "match_field": "_id", "enrich_fields": ["key"] } } # 执行策略,生成关联数据 POST /_enrich/policy/stat_data_policy/_execute # 创建Ingest管道,用来给STAT GROUP添加关联的STAT DATA字段 PUT /_ingest/pipeline/stat_group_enrich_pipeline { "processors": [ { "enrich": { "policy_name": "stat_data_policy", "field": "statValues._ref", "target_field": "statValues.statData", "max_matches": 1 } } ] } # 把STAT GROUP重新索引到新索引(或更新现有文档),自动关联数据 POST /stat_group_enriched_index/_doc/38282922829?pipeline=stat_group_enrich_pipeline { "statValues": [ { "_ref": "282828290" } ] }
处理完后,STAT GROUP的statValues里会直接包含对应的statData字段,查询起来特别方便。
方案三:直接嵌套文档(适合数据生命周期一致的场景)
如果STAT DATA和STAT GROUP是绑定在一起的,不需要单独维护,那最简单的方式就是把STAT DATA的内容直接嵌入到STAT GROUP的statValues数组里:
PUT /stat_combined_index/_doc/38282922829 { "statValues": [ { "_ref": "282828290", "key": "itemsGained" } ] }
这种方式查询性能最好,不需要任何关联操作,适合数据不会单独更新的场景。
内容的提问来源于stack exchange,提问作者DragonFyZex

