之前有个业务需求,由于最开始存储到es里的,是默认空字符串,后面程序取数据时,发现需要取空字符串的数据时,不好取出来。
字符串的字段如图:
实际数据如图:
用的是C#语言,使用的是Elasticsearch.Net和Nest两个类库,查找字符串为空的数据。
最开始找网上的资料,使用的判断条件是MustNot+Term:
Func<QueryContainerDescriptor<HotModelEsModel>, QueryContainer> query =
q => q.Bool(a => a.MustNot(m => m.Term(f => f.DataDate, "")));
对应的Request是:
竟然把我的条件去掉了!拿到的结果自然就是错的。
只能再继续找资料,使用新的判断条件是MustNot+Wildcard:
Func<QueryContainerDescriptor<HotModelEsModel>, QueryContainer> query =
q => q.Bool(a => a.MustNot(m => m.Wildcard(f => f.DataDate, "*")));
对应的Request是:拿到的结果却是空的。
只能继续查找资料,使用Script方式:
Func<QueryContainerDescriptor<HotModelEsModel>, QueryContainer> query =
q => q.Script(c => c.Script(d => d.Source("doc['DataDate'].value==''").Lang(ScriptLang.Painless)));
对应的Request是:
终于完美拿到结果了!
但是Script相对来说效率会低一点点,不到万不得已不使用。
因为之前问过大佬,大佬给了一个新的解决方案Terms+Verbatim:
Func<QueryContainerDescriptor<HotModelEsModel>, QueryContainer> query =
q => q.Terms(tf => tf.Verbatim().Field(t => t.DataDate).Terms(new string[] { "" }));
对应的Request是:
也成功了!
把大佬的方案再优化一下,使用Term+Verbatim:
Func<QueryContainerDescriptor<HotModelEsModel>, QueryContainer> query =
q => q.Term(c => c.Verbatim().Field(p => p.DataDate).Value(""));
对应的Request是:
完美拿到想要的数据!
拿到数据之后,查了一下Verbatim,这个是用于不分词,完全按照搜索条件去搜索。
所以可以完整地匹配空字符串。