一日一技:在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:00到2019-11-29 00:00:00,並且source欄位為baidu,title欄位包含青南但是不包含大神的數據。

但需要注意的是,使用通配符搜索,會對 ES 集群造成比較大的壓力,特別是*號在前時,會有一定的性能損耗。

Tags: