最近需要查询某个字段既不为null也不为"",但网上有很多关于ES查询某些字段为null和""的博文,研究了一下,发现有三种方案。
方案一: 使用existsQuery关键字,查询出某些字段存在(值为null)的条目,但是不能过滤出值为""的字段
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
List<QueryBuilder> must = boolQueryBuilder.must();
must.add(QueryBuilders.boolQuery().must((QueryBuilders.existsQuery("字段名称"))));
方案二:使用wildcardQuery关键字
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
List<QueryBuilder> must = boolQueryBuilder.must();
//星号表示所有,即:不为空的字段
must.add(QueryBuilders.wildcardQuery("字段名称", "*"));
方案三:使用ASCII码比较,首先,null的ASCII是0,空格的ASCII是32,空字符的ASCII好像也是0(此处有些疑问
),此时我们可以用范围比较。
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
List<QueryBuilder> must = boolQueryBuilder.must();
RangeQueryBuilder range = QueryBuilders.rangeQuery("字段名称");
//ASCII码大于0(此处为0时,字段值为""的条目不会显示,因此有""的ASCII值也是0的判断)
range.gt(0);
must.add(range);
补充:
1. 方案一是最好的方案。ES中,某个字段的值为null,它不会显示出来;若为"",则会显示出来。问题就在这儿,方案一虽好,但是不合乎要求,所以往ES中添加数据时,一定不要写入空字符串
,因为这无疑时给自己找麻烦。
2. 方案二是模糊查询,据说
效率最低,查询最耗资源。我目前用的就是这个,因为我在将近5000万数据中查询毫无问题,返回速度也就50多毫秒(做了翻页),不知道在高并发情况下会如何,以后要是出了问题在和大家报备。
3. 方案三是利用ASCII码进行范围查询,速度没有问题,至于高并发情况下也没有测试。