PHP操作Elasticsearch时排除Hierarchy字段参与搜索的方法
问题描述
我的Elasticsearch索引数据结构如下:
"id": "162d2df9-16e0-4171-bc54-52f2b3a4a23c", "uri": "https://local.test.com/abc", "title": "Geography", "dateTime": "2022-06-15T09:32:37+00:00", "type": "Default", "hcs": "Primary", "lE": "1", "otherData": { "id": "57907298-3945-4654-a75a-7278bcb14399", "uri": "https://local.test.com/gcsp", "title": "GCSP" }, "moreData": { "id": "48e939c5-c4f3-4cf2-ae2d-8d964682361d", "uri": "https://local.test.com/xyz", "title": "Default" }, "Hierarchy": { "data": { "id": "57907298-3945-4654-a75a-7278bcb14399", "title": "GCSP" }, "parent": [ { "id": "162d2df9-16e0-4171-bc54-52f2b3a4a23c", "title_fs": "Maths", "hcs_p": "Primary", "parent": [ { "id": "ddff7857-f8be-45a1-b41d-aef2207ff66b", "title_fs": "Civics", "hcs_p": "Primary", "parent": [ { "id": "24d126e2-464b-499b-b2c0-adcd7a7b7728", "title_fs": "History", "hcs_p": "Primary", "parent": [ { "id": "23a094da-33b8-4960-8daa-8291e6634305", "title_fs": "Science", "hcs_p": "Primary", "parent": [ { "id": "32de28ab-5bd5-4cd6-9dc9-f9766fcdfab3", "title_fs": "Subjects", "hcs_p": "Primary", "parent": [] } ] } ] } ] } ] } ] }
我需要在搜索、结果返回环节排除Hierarchy字段的内容,之前尝试的写法没有生效:
['bool']['must'][] = [ "multi_match" => [ "operator" => "and", "query" => $searchTerm, "fields" => ["*", "Hierarchy"] ] ];
解决方案
你之前的写法不生效核心原因有两个:
fields配置里的*本身就会匹配所有可搜索字段,追加Hierarchy只是重复指定该字段参与匹配,完全没有实现排除逻辑- Elasticsearch字段通配符规则中,排除指定字段需要在字段名前加
-前缀,对于嵌套对象字段,还要同步排除其下所有子字段,否则深层嵌套的子字段依然会参与匹配
1. 搜索匹配阶段排除Hierarchy字段
修改multi_match的fields配置,匹配全量字段后显式排除Hierarchy及其所有子字段:
['bool']['must'][] = [ "multi_match" => [ "operator" => "and", "query" => $searchTerm, "fields" => ["*", "-Hierarchy", "-Hierarchy.*"] ] ];
注意:如果使用7.x以下版本的Elasticsearch,需要确认
indices.query.bool.max_clause_count参数配置足够,避免字段过多触发查询子句数量限制。
2. 结果返回阶段排除Hierarchy字段
如果不需要返回结果中包含Hierarchy的内容,在查询最外层加_source过滤规则即可:
[ "_source" => [ "excludes" => ["Hierarchy", "Hierarchy.*"] ], "query" => [ // 此处放上述bool查询逻辑 ] ]
永久优化方案
如果业务场景永久不需要用Hierarchy字段做检索,最高效的方案是创建索引映射时,给Hierarchy字段设置"index": false,这样该字段不会生成倒排索引,从根源上不参与搜索匹配,还能节省索引存储开销,需要返回字段内容时依然可以从_source中获取。
内容的提问来源于stack exchange,提问作者Bhumi Shah
相关产品推荐
相关产品推荐

