Elasticsearch将字符串与空格,列和破折号精确匹配

时间:2020-08-31 22:14:58

标签: elasticsearch full-text-search

我正在使用Elasticsearch 6.8,并尝试在python笔记本中编写查询。这是用于我正在使用的索引的映射:

{ "mapping": { "news": { "properties": { "dateCreated": { "type": "date", "format": "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis" }, "itemId": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "market": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "timeWindow": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "title": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } } } }

我正在尝试在“ timeWindow”字段中搜索精确字符串,例如“ [2020-08-16 10:00:00.0,2020-08-16 11:00:00.0]” (这是“文本”类型,而不是“日期”字段),还可以通过market =“ zh-cn”选择(市场也是“文本”字段)。该字符串包含空格,冒号,逗号,很多白色字符,而且我不知道如何进行正确的查询。

此刻我有以下查询:

res = es.search(index='my_index', 
    doc_type='news', 
    body={
    'size': size,
    'query':{
        "bool":{
            "must":[{
                "simple_query_string": {
                    "query": "[2020-08-17 00:00:00.0,2020-08-17 01:00:00.0]",
                    "default_operator": "and",
                    "minimum_should_match":"100%"
                }
            },
            {"match":{"market":"en-us"}}
            ]
        }  
    }
})

问题在于与timeWindow字符串的“ simple_query_string”不完全匹配(我知道该字符串已被标记化,分为“ 2020”,“ 08”,“ 17”,“ 00”,“ 01”,等等,并且分别分析每个令牌),并且我要排除的timeWindow的值有所不同,例如

['[2020-08-17 00:00:00.0,2020-08-17 01:00:00.0]'
 '[2020-08-17 00:05:00.0,2020-08-17 01:05:00.0]'
 ...
 '[2020-08-17 00:50:00.0,2020-08-17 01:50:00.0]'
 '[2020-08-17 00:55:00.0,2020-08-17 01:55:00.0]'
 '[2020-08-17 01:00:00.0,2020-08-17 02:00:00.0]']

有没有办法做我想做的事?

UPD(和答案): 我当前的查询使用“ term”和“ timeWindow.keyword”,这种组合使我能够精确搜索包含空格和其他白色字符的字符串:

res = es.search(index='msn_click_events', doc_type='news', body={
    'size': size,
    'query':{
            "bool":{
                "must":[{
                    "term": {
                        "timeWindow.keyword": tw
                    }
                },
                {"match":{"market":"en-us"}}
                ]
            }  
        }
    })

此查询仅选择正确的timewindows值(字符串):

['[2020-08-17 00:00:00.0,2020-08-17 01:00:00.0]'
 '[2020-08-17 01:00:00.0,2020-08-17 02:00:00.0]'
 '[2020-08-17 02:00:00.0,2020-08-17 03:00:00.0]'
 ...
 '[2020-08-17 22:00:00.0,2020-08-17 23:00:00.0]'
 '[2020-08-17 23:00:00.0,2020-08-18 00:00:00.0]']

1 个答案:

答案 0 :(得分:1)

在您的timeWindow字段上,您需要一个keyword aka exact search,但是您正在使用全文查询,并且在将该字段定义为text字段时,您已经猜到它是正确的,它会在索引期间进行了分析,因此您没有获得正确的结果。

如果您使用动态映射,则将为映射中的每个.keyword字段生成text字段,因此您可以在查询中简单地使用timeWindow.keyword即可使用

如果已定义映射,则无需添加关键字字段来存储timewindow,请重新索引数据并在查询中使用该keyword字段以获得预期结果。

相关问题