首页 > 解决方案 > 当查询文本为字母数字模式时,Elasticsearch 将返回所有记录

问题描述

我在 Elasticsearch 中有一个索引,其映射为:

/price_validity_idx

{
  "mappings": {
    "properties": {
      "title":{
        "type": "text"
      },
      "validity":{
        "type": "boolean"
      }
    }
  }
}

该索引中存储的数据如下所示:

{
 "title" : "16 USD product"
"validity": true
}
{
 "title" : "USD 5 refill"
"validity": true
}
.....
{
 "title" : "10 USD"
"validity": false
},
{
"title" : "Movies on Demand-Free of cost"
"validity": false
},
{
"title" : "One month subscription on Cash purchase"
"validity": true
}

因此,每当我对字段标题进行匹配查询时,查询文本为字母数字(例如 5 美元),标题中具有数值的所有记录都会作为结果的一部分返回。

例如 curl -XGET '/price_validity_idx' -d '{"query":{"match": { "title": "USD 5" } }}'

输出:(删除弹性搜索元信息以实现紧凑性

{
 "title" : "16 USD product"
"validity": true
},
{
 "title" : "USD 5 refill"
"validity": true
},
{
 "title" : "10 USD"
"validity": false
}

但是,每当我对字段标题进行相同的匹配查询时,仅将数字作为查询文本(例如 5),就会返回与数字匹配的特定记录。

当查询文本为字母数字(例如 5 美元)时,如何使其仅返回与确切数值匹配的记录。由于某些业务限制,我将无法将映射类型更改为INTEGER。此外,我将无法使用 TERM 查询,因为该字段还包含一些冗长的文本数据。

请帮忙,因为我是 Elasticsearch 的新手。

使用的版本是 Elasticsearch-7.8.1

标签: elasticsearchsearchfull-text-searchelastic-stackanalyzer

解决方案


标准分析器是在没有指定时使用的默认分析器。生成的标记是usdand 5,因此与这些标记中的任何一个匹配的所有文档都将匹配搜索查询。

分析 API

GET/ _analyze
{
  "analyzer" : "standard",
  "text" : "USD 5"
}

生成以下令牌:

{
  "tokens": [
    {
      "token": "usd",
      "start_offset": 0,
      "end_offset": 3,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "5",
      "start_offset": 4,
      "end_offset": 5,
      "type": "<NUM>",
      "position": 1
    }
  ]
}

您可以使用match_phrase 查询来分析文本并根据分析的文本创建短语查询。

搜索查询:

{
  "query": {
    "match_phrase": {
      "title": "USD 5"
    }
  }
}

搜索结果:

"hits": [
      {
        "_index": "64528215",
        "_type": "_doc",
        "_id": "2",
        "_score": 2.1446278,
        "_source": {
          "title": "USD 5 refill",
          "validity": true
        }
      }
    ]

编辑1:

您甚至可以将match 查询与 operator 一起使用AND,这是一个布尔逻辑,用于解释查询值中的文本

{
  "query": {
    "match": {
      "title": {
        "query": "USD 5",
        "operator": "and"
      }
    }
  }
}

推荐阅读