一日一技:在ES中如何使用通配符搜索keyword字段

  • 2019 年 11 月 30 日
  • 笔记

游玩:kingname & 产品经理

我们知道,在 ES 中,字段类型如果是keyword,那么在搜索的时候一般只能整体搜索,不支持搜索部分内容。例如,有一个字段叫做{"name": "我是青南"},当我使用{"match": {"name": "我是青南"}}的时候可以正常搜索出来。但是当我使用{"match": {"name": "青南"}}时,就什么都搜索不到。

但是,ES 支持使用通配符来进行搜索,于是我们可以把 DSL 搜索语句构造为:

{"wildcard": {"name": "*青南*"}}

这样就能正常搜索出结果了。

下面给出一段可以正常使用的elasticsearch-py的代码,用于编写 DSL 语句在 Elasticsearch 中搜索数据:

from elasticsearch import Elasticsearch, helpers  es = Elasticsearch([{'host': 'xx.xx.xx.xx', 'port': 1234}], timeout=30)    body = {          "query": {              "bool": {                  "filter": [                      {                        "range": {                            "ts": {                                "gte": '2019-11-01 00:00:00',                                "lt": '2019-11-29 00:00:00'                            }                        },                      }                  ],                  'must': [                      {'match_phrase': {'source': 'baidu'}},                      {'wildcard': {'title': '*青南*'}}                  ],                  "must_not": [                       {'wildcard': {'title': {'value': '*大神*'}}}                  ],              }          },          }  res = es.search(index='spider_data', body=body)  print(res)

这段代码的意思是说:

搜索 ts 时间范围在2019-11-01 00:00:002019-11-29 00:00:00,并且source字段为baidutitle字段包含青南但是不包含大神的数据。

但需要注意的是,使用通配符搜索,会对 ES 集群造成比较大的压力,特别是*号在前时,会有一定的性能损耗。