ElasticSearch多对多映射查询:获取特定所有者关联产品信息
解决特定所有者的所有产品信息查询问题
嘿,我来帮你优化这个查询流程!你现在的两步查询法虽然能实现需求,但确实可以优化成更高效的单次查询,或者先调整数据结构让查询更顺畅。下面分几种情况给你方案:
一、优先优化数据结构(最推荐)
你的Owner类型里Products字段是CSV格式的字符串,这种格式在查询时需要额外拆分处理,效率不高。建议把它改成字符串数组类型,修改后的Owner文档结构如下:
{"OwnerId":"o-id1", "Products":["P1","P2","P3"]}
这样调整后,你可以直接用Elasticsearch的terms查询结合跨索引查找,一次性拿到目标所有者的所有产品:
GET /product/_search { "query": { "terms": { "ProductId": { "index": "owner", // 指定Owner类型所在的索引 "id": "o-id1", // 目标所有者的文档ID "path": "Products" // 从Owner文档的Products字段取ID列表 } } } }
这种方法的优势是查询效率极高,完全利用ES的原生索引能力,没有额外的脚本开销。
二、不修改数据结构的情况下实现单次查询
如果暂时不能调整Owner的字段格式,也可以用Painless脚本配合参数查找来实现单次查询:
GET /product/_search { "query": { "bool": { "filter": { "script": { "script": { "source": "doc['ProductId'].value in params.productIds", "params": { "productIds": "${lookup}" }, "lang": "painless" } } } } }, "params": { "lookup": { "index": "owner", "id": "o-id1", "path": "Products", "transform": "x -> x.split(',')" // 把CSV字符串拆分成数组 } } }
注意:这种方法会用到脚本执行,在数据量较大时性能会比第一种方案差一些,所以还是优先推荐调整数据结构。
三、保留你的两步法但优化细节
如果你还是想保留两步查询的逻辑,可以优化第二步的查询,用terms查询代替多个match,减少查询开销:
- 第一步查询Owner获取Products字符串,拆分得到ID数组:
GET /owner/_doc/o-id1
得到结果后拆分Products字段为["P1","P2","P3"]。
- 第二步用
terms查询Product:
GET /product/_search { "query": { "terms": { "ProductId": ["P1","P2","P3"] } } }
这种方法逻辑简单,适合数据量不大的场景,但多次请求会增加网络开销。
内容的提问来源于stack exchange,提问作者Jainendra
相关产品推荐
相关产品推荐

