游玩: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 集群造成比较大的压力,特别是*号在前时,会有一定的性能损耗。