Elasticsearch long类型字段子值匹配查询方法咨询
问题根因
你当前的查询无法得到预期结果,核心原因是field1为long数值类型,Elasticsearch默认不会对数值类型字段执行字符串形式的子串匹配,通配符查询规则对数值类型字段不生效。
方案1:无需修改现有索引(性能较差,仅适合小数据量场景)
直接通过脚本查询将long字段转为字符串后做包含判断,如果存在field1为空的文档,需要在脚本中增加非空判断避免报错。
NEST 写法
long tempValue = 12; string targetSub = tempValue.ToString(); query &= filtreQuery.Script(s => s .Source("doc['field1'].size() > 0 ? doc['field1'].value.toString().contains(params.targetSub) : false") .Params(p => p.Add("targetSub", targetSub)) );
对应原生ES查询DSL
{ "query": { "script": { "script": { "source": "doc['field1'].size() > 0 ? doc['field1'].value.toString().contains(params.targetSub) : false", "params": { "targetSub": "12" } } } } }
方案2:修改索引映射(性能最优,推荐生产环境使用)
提前给field1增加字符串类型的子字段,后续直接查询子字段即可,查询效率远高于脚本查询。
第一步:调整索引映射
给field1新增keyword类型的子字段str:
PUT overlog-mouvement-index/_mapping { "properties": { "field1": { "type": "long", "fields": { "str": { "type": "keyword" } } } } }
修改映射后需要重新索引所有历史数据,让新增的子字段生效。
第二步:编写查询语句
如果需要匹配任意位置的子串,使用通配符查询:
long tempValue = 12; query &= filtreQuery.Wildcard(w => w .Field(f => f.field1.Suffix("str")) .Value($"*{tempValue}*") );
如果仅需要匹配开头的子串(比如数字以12开头),使用前缀查询性能更高:
long tempValue = 12; query &= filtreQuery.Prefix(p => p .Field(f => f.field1.Suffix("str")) .Value(tempValue.ToString()) );
内容的提问来源于stack exchange,提问作者oumechtak
相关产品推荐
相关产品推荐

