如何将Elasticsearch字段同时设为keyword和text类型实现聚合与全文检索
解决方案
ES原生支持同一字段同时适配多种查询场景,以下是两种可直接落地的实现方式:
方案1:优先使用多字段(multi-fields)映射(最推荐)
这是ES官方为同一字段支持多种索引规则设计的原生特性,无需依赖copy_to即可满足需求,也可以和你现有的copy_to逻辑共存。
正确的索引Schema配置
"stockLocation": { "type": "object", "properties": { "full_text": { "type": "text", "analyzer": "custom_analyzer" }, "city": { "type": "keyword", "copy_to":"full_text", "fields": { "text": { "type": "text", "analyzer": "custom_analyzer" } } }, "country": { "type": "keyword", "copy_to":"full_text", "fields": { "text": { "type": "text", "analyzer": "custom_analyzer" } } } } }
使用规则
- 聚合操作保持现有代码不变,直接使用
StockLocation.City、StockLocation.Country(keyword类型,聚合逻辑完全兼容) - 如需单独对城市/国家做全文检索,使用子字段路径
StockLocation.City.text、StockLocation.Country.text - 全局跨字段全文检索依然可以使用
full_text字段
方案2:修复现有copy_to逻辑的问题
你当前的copy_to配置本身是生效的,查询无结果是因为SimpleQueryString默认不会主动查询你自定义的full_text字段,需要显式指定检索字段:
var qieryDescriptor = query.SimpleQueryString(p => p .Query(searchQuery.FreeText) .Field(f => f.StockLocation.FullText) );
如果需要同时检索多个字段,可多次调用Field方法传入对应路径即可。
注意事项
修改索引映射后需要重建索引或者对历史数据执行Reindex操作,旧数据不会自动应用新的映射规则。
如果使用NEST特性映射自动生成索引,可直接在实体类属性上加注解实现多字段配置,示例如下:
public class StockLocation { [Keyword(CopyTo = new []{ "stockLocation.full_text" })] [Text(Name = "text", Analyzer = "custom_analyzer")] public string City { get; set; } [Keyword(CopyTo = new []{ "stockLocation.full_text" })] [Text(Name = "text", Analyzer = "custom_analyzer")] public string Country { get; set; } }
内容的提问来源于stack exchange,提问作者Bagaboo
相关产品推荐
相关产品推荐

