ElasticSearch 记一次分词导致的查询不准确问题


es term 结果不符合预期

es 使用term进行精确匹配时发现,并不能正确得找到想要的值。
比如明明有某个field的值为-1,在term查询时得到结果为空

GET /my_index/_search
{
  "query": {
    "term": {
      "code": "-1"
    }
    
  }
}


{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 0,
    "max_score": null,
    "hits": []
  }
}

原因是es对数据存储的时候进行的词义分析,将分析后的结果进行存储。
在本例中 -1 已经被 解析为 1,再进行查询时,自然是找不到-1了。


查看词义分析的方法

GET /my_index/_analyze
{
  "field": "code",
  "text": "-1"
}

结果
{
  "tokens": [
    {
      "token": "1",
      "start_offset": 1,
      "end_offset": 2,
      "type": "",
      "position": 0
    }
  ]
}

官方文档说明:
https://www.elastic.co/guide/en/elasticsearch/guide/2.x/_finding_exact_values.html#_term_query_with_numbers



解决方法:
将该mapping设为数字,或者设置为不解析

自动生成的mapping为
...
"code": {
  "type": "text",
  "fields": {
    "keyword": {
      "type": "keyword",
      "ignore_above": 256
    }
  }
}
...

改成
...
"code": {
  "type": "long",
  "fields": {
    "keyword": {
      "type": "keyword"
    }
  }
}
...

或者

...
"code": {
  "type": "string",
  "index" : "not_analyzed"
}
...


实例
PUT my_index
{
  "mappings": {
    "my_type": {
      "properties": {
        "code": {
          "type": "string",
          "index": "not_analyzed"
        }
      }
    }
  }
}

#my_type任意命名。
经测试,可单独设置一个字段的配置,其他字段在第一次插入时会自动配置。
该字段配置后,会对所有type生效。
该配置仅能在index创建时使用。如果已经有输入插入,则无法修改。如需修改请见官方文档。


验证
词义分析验证
GET /my_index/_analyze
{
  "field": "code",
  "text": "-1"
}

"reason": "Can't process field [code], Analysis requests are only supported on tokenized fields"

查询验证
GET /my_index/_search
{
  "query": {
    "term": {
      "code": "-1"
    }
    
  }
}


{
  "took": 7,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.2876821,
    "hits": [
...
"code": "-1",
...


相关命令
GET my_index/_mapping
DELETE my_index


你可能感兴趣的:(Elasticsearch)