Elasticsearch中如何对含多字段的嵌套字段进行排序?
Elasticsearch嵌套字段排序报错解决方案
我首次提问,想找到Elasticsearch中嵌套字段排序的正确方法,目前遇到400错误,报错提示找不到嵌套对象路径,相关信息如下:
主实体类定义
public class SignalementConflitRechercheAvanceeDocument extends SignalementConflitNestedRechercheAvanceeDocument{ private static final long serialVersionUID = 1L; // Objet(s) de croisement @Field(type = FieldType.Nested) private EtablissementNestedRechercheAvanceeDocument etablissementRechercheAvanceeDocument; }
嵌套对象定义
public class EtablissementNestedRechercheAvanceeDocument implements Serializable { protected static final long serialVersionUID = 1L; @Id @MultiField(mainField = @Field(type = FieldType.Text, analyzer = "index-analyzer", searchAnalyzer = "search-analyzer"), otherFields = { @InnerField(suffix = "tri", type = FieldType.Keyword, normalizer = "sort-normalizer") }) protected String siret; @Field(type = FieldType.Boolean) protected boolean secteur; @Field(type = FieldType.Keyword) protected String siren; @Field(type = FieldType.Long) protected Long regId; @MultiField(mainField = @Field(type = FieldType.Text), otherFields = { @InnerField(suffix = "tri", type = FieldType.Keyword) }) protected String libelleRegion; }
Elasticsearch字段映射
"regId": { "type": "long" }, "secteur": { "type": "boolean" }, "siren": { "type": "keyword" }, "siret": { "type": "text", "fields": { "tri": { "type": "keyword", "normalizer": "sort-normalizer" } }, "analyzer": "index-analyzer", "search_analyzer": "search-analyzer" }, "libelleService": { "type": "text", "fields": { "tri": { "type": "keyword" } } },
尝试的查询请求
{ "query": { "bool": { "must": [ { "nested": { "query": { "bool": { "must": [ { "bool": { "should": [ { "match": { "etablissementRechercheAvanceeDocument.secteur": { "query": "false", "operator": "OR", "prefix_length": 0, "max_expansions": 50, "fuzzy_transpositions": true, "lenient": false, "zero_terms_query": "NONE", "auto_generate_synonyms_phrase_query": true, "boost": 1 } } } ], "adjust_pure_negative": true, "boost": 1 } } ], "adjust_pure_negative": true, "boost": 1 } }, "path": "etablissementRechercheAvanceeDocument", "ignore_unmapped": false, "score_mode": "max", "boost": 1, "inner_hits": { "ignore_unmapped": false, "from": 0, "size": 100, "version": false, "seq_no_primary_term": false, "explain": false, "track_scores": false } } } ], "adjust_pure_negative": true, "boost": 1 } }, "sort": [ { "etablissementRechercheAvanceeDocument.siret.tri": { "order": "asc", "nested":{ "path": "etablissementRechercheAvanceeDocument.siret", } } } ] }
错误信息
Error 400. {"error":{"root_cause":[{"type":"query_shard_exception","reason":"[nested] failed to find nested object under path [etablissementRechercheAvanceeDocument.siret]","index_uuid":"lGwiXFs4RDCIZ6jqGVzPYQ","index":"signalement-conflit-recherche-avancee-doc"}],"type":"search_phase_execution_exception","reason":"all shards failed","phase":"query","grouped":true,"failed_shards":[{"shard":0,"index":"signalement-conflit-recherche-avancee-doc","node":"WKtmnvO8SdOBplHuGeLxIw","reason":{"type":"query_shard_exception","reason":"[nested] failed to find nested object under path [etablissementRechercheAvanceeDocument.siret]","index_uuid":"lGwiXFs4RDCIZ6jqGVzPYQ","index":"signalement-conflit-recherche-avancee-doc"}}]},"status":400}
问题原因及修复方案
报错核心是sort配置中的nested路径错误:etablissementRechercheAvanceeDocument.siret不是嵌套对象路径,真正的嵌套对象根路径是etablissementRechercheAvanceeDocument,siret只是该嵌套对象下的字段,siret.tri是siret的多字段子项。
修复后的sort部分需将nested.path指定为嵌套对象的根路径:
"sort": [ { "etablissementRechercheAvanceeDocument.siret.tri": { "order": "asc", "nested":{ "path": "etablissementRechercheAvanceeDocument" } } } ]
完整修复后查询请求
{ "query": { "bool": { "must": [ { "nested": { "query": { "bool": { "must": [ { "bool": { "should": [ { "match": { "etablissementRechercheAvanceeDocument.secteur": { "query": "false", "operator": "OR", "prefix_length": 0, "max_expansions": 50, "fuzzy_transpositions": true, "lenient": false, "zero_terms_query": "NONE", "auto_generate_synonyms_phrase_query": true, "boost": 1 } } } ], "adjust_pure_negative": true, "boost": 1 } } ], "adjust_pure_negative": true, "boost": 1 } }, "path": "etablissementRechercheAvanceeDocument", "ignore_unmapped": false, "score_mode": "max", "boost": 1, "inner_hits": { "ignore_unmapped": false, "from": 0, "size": 100, "version": false, "seq_no_primary_term": false, "explain": false, "track_scores": false } } } ], "adjust_pure_negative": true, "boost": 1 } }, "sort": [ { "etablissementRechercheAvanceeDocument.siret.tri": { "order": "asc", "nested":{ "path": "etablissementRechercheAvanceeDocument" } } } ] }
补充说明
- 嵌套排序时,
nested.path必须指向定义为nested类型的字段,即实体类中被@Field(type = FieldType.Nested)标注的etablissementRechercheAvanceeDocument,而非其子字段。 - 若嵌套对象包含多个元素,可通过
nested.filter指定参与排序的嵌套元素范围,保证排序逻辑符合预期。
内容的提问来源于stack exchange,提问作者Feideus
相关产品推荐
相关产品推荐

