elasticsearch匹配空字符串的问题

es中有这么一篇文档:

{
    "_index": "xsq_tickets.v1",
    "_type": "xsq_tickets",
    "_id": "85336",
    "_version": 1,
    "found": true,
    "_source": {
        "actCode": "20170906004",
        "leftQuantity": 18,
        "leftSeatNo": "",
        "priceMethod": 1,
        "priceSecSort": 12986,
        "priceUnit": "张",
        "pubDatetime": "2017-09-06 16:42:17",
        "quantity": 18,
        "remark": "",
        "reviewDatetime": "0000-00-00 00:00:00",
        "rows": "",
        "salerType": 2,
        "seatNo": "",
        "ticketsFeature": "",
        "ticketsId": 85336
    }
}

如果我的查询条件是:

{
    "query":{
        "bool":{
            "must":[
                {
                    "term":{
                        "ticketsId":85336
                    }
                }
            ]
        }
    }
}

那么可以匹配到上面这篇文档,但是我现在想把字段 rows 为空的结果过滤掉:

{
    "query":{
        "bool":{
            "must":[
                {
                    "term":{
                        "ticketsId":85336
                    }
                }
            ],
            "must_not": [
                {
                    "term":{
                        "rows":""
                    }
                }    
            ]
        }
    }
}

我多加了一个must_not过滤掉rows 为空的文档,但是似乎没有效果,依然会返回上面的那篇文档,我这么写是哪里有问题么?正确的写法应该是什么样的,求教

阅读 24.7k
5 个回答

最终这问题还是被解决了,之前设置索引的mapping的时候rows字段类型为text,默认会被分词,后来重建了索引,修改了mapping将原来text的类型改成了keyword,这样rows字段就不会被分词器分词,就可以实现精准查询了,修改了mapping之后,上面的查询语句就生效了。

这个周末抽个时间好好深入研究下这个问题

新手上路,请多包涵

两点补充。
1.还有一个办法。想过滤空的,反过来就是指一定得要有内容嘛。可以用通配符query。这样也不用重建index。
GET mytest/_search
{

"query":{
 "wildcard": { 
  "rows": "*" 
} 
}

}
我测试过应该是可以的。。。

2.另外,和题主一样,改成keyword后确实must not就奏效了。原因得研究一下。。。有大神说一下么。

字段加上.keyword 即可

"must_not": [
                {
                    "term":{
                        "rows.keyword":""
                    }
                }    
            ]
新手上路,请多包涵

当值是空字符串的时候,分词的接口是一个空的token list,es并没有提供类似exists的查询去判断一个字段的token list是否为空。
所以要判断一个text字段是否是空字符串的时候,可以考虑使用fields即一个字段多类型。

新手上路,请多包涵

我一直查找这个判断为空字符串的识别,这两个设置是最有效的,增加keyword我是在kibana下查看具有aggregatable,看是有带有keyword的才具有这能力

方式一.查找数据不为空字符串且必须有值

GET devl-event*/_search
{
"size": 50,

"query": {
  "bool": {
    "must": [
      {
        "exists": {
          "field": "clientId.keyword"
        }
      }
    ],
    "must_not": [
      {
        "term": {
          "clientId.keyword": {
            "value": ""
          }
        }
      }
    ]
  }
}

}

方式二.查找数据不为空字符串且必须有值

GET devl-event*/_search
{
"size": 40,

"query": {
  "wildcard": {
    "clientId": {
      "value": "*"
    }
  }
}

}

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进