ElasticSearch父子文档查询:匹配内容并返回代码段求助
解决ElasticSearch父子文档查询及高亮问题
首先得先明确你的Elasticsearch版本,因为不同版本的父子关系查询语法差异很大,这大概率是你之前尝试无效的核心原因。下面分两种场景给你针对性的解决方案:
场景1:使用ES 5.x及更早版本(支持多Type)
这个版本里父文档Type是document,子文档Type是page,且子文档创建时已指定_parent字段关联父文档ID。
正确查询代码(推荐用Filter,不影响评分更高效)
[ 'size' => 100, 'from' => 0, // 高亮配置保持不变 'highlight' => [ 'fields' => [ 'content' => (object)[] ] ], 'query' => [ 'bool' => [ 'must' => [ // 匹配内容搜索字符串 'match' => [ 'content' => $_GET['search'] ] ], 'filter' => [ // 过滤指定父文档下的子文档 'term' => [ '_parent' => $hit['_id'] ] ] ] ] ];
也可以用parent_id查询
[ 'size' => 100, 'from' => 0, 'highlight' => [ 'fields' => [ 'content' => (object)[] ] ], 'query' => [ 'bool' => [ 'must' => [ 'match' => [ 'content' => $_GET['search'] ], 'parent_id' => [ 'type' => 'page', // 子文档的Type 'id' => $hit['_id'] ] ] ] ] ];
场景2:使用ES 6.x+版本(仅支持单Type,需用Join字段)
这个版本不再支持多Type,父子关系需要通过专门的Join字段定义,比如你的索引映射应该类似这样:
{ "mappings": { "_doc": { "properties": { "join_field": { "type": "join", "relations": { "document": "page" // document是父角色,page是子角色 } }, "content": { "type": "text" } } } } }
方法A:用parent_id查询(性能最优)
[ 'size' => 100, 'from' => 0, 'highlight' => [ 'fields' => [ 'content' => (object)[] ] ], 'query' => [ 'bool' => [ 'must' => [ 'match' => [ 'content' => $_GET['search'] ] ], 'filter' => [ 'parent_id' => [ 'field' => 'join_field', // 你的Join字段名称 'type' => 'page', // 子角色名称 'id' => $hit['_id'] ] ] ] ] ];
方法B:修正has_parent查询(你之前的参数写错了)
你之前的has_parent里用了type参数,这是错误的,ES要求用parent_type指定父角色:
[ 'size' => 100, 'from' => 0, 'highlight' => [ 'fields' => [ 'content' => (object)[] ] ], 'query' => [ 'bool' => [ 'must' => [ 'match' => [ 'content' => $_GET['search'] ], 'has_parent' => [ 'parent_type' => 'document', // 父角色名称,替换成你的实际值 'query' => [ 'ids' => [ 'values' => [$hit['_id']] ] ] ] ] ] ] ];
常见错误排查
- 参数名称错误:
has_parent必须用parent_type而非type,这是你之前报错的核心原因之一; - 版本不兼容:6.x+版本不能再用
_parent字段过滤,必须使用Join字段对应的查询语法; - 父子关联错误:确保创建子文档时,正确关联了父文档ID(5.x用
_parent参数,6.x+用Join字段的parent参数); - PHP语法错误:检查数组逗号分隔是否正确,避免语法解析导致的无效请求。
内容的提问来源于stack exchange,提问作者Alex Brandsen
相关产品推荐
相关产品推荐

