Elasticsearch中一个空字符串引起的思考

2020-10-28  本文已影响0人  ochipe
一:空字符串的坑

使用Elasticsearch时间比较长了,很多时候停留在会使用阶段,直到昨天遇到一个空字符串的问题,思考了很久,发现其实很多东西只是停留在认知阶段,下面分析下坑的来源以及解决办法。

二:场景:

我有一个content字段配置了分词,需要进行搜索,type设置的是text,
并不是我所期待的结果
查了资料,[Elasticsearch Reference [7.9] » Mapping » Mapping parameters » null_value
]https://www.elastic.co/guide/en/elasticsearch/reference/current/null-value.html
其实发现这个并不是自己想要的结果,但是为了验证怎么才能查出来是空字符串的数据这个问题,猜到了大概跟mapping中type设置应该有关系,因此尝试默认mapping的方式,这时候发现出来的结果才是正确的,但是有一个问题,分词问题,因此在默认mapping基础上尝试了加上分词设置,具体操作如下


PUT /index_001/
{
  "mappings": {
    "properties": {
      "id": {
        "type": "keyword"
      },
      "content": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart"
      }
    }
  }
}

POST /index_001/_doc/1
{
  "id":"1",
  "content":"华为手机"
}
POST /index_001/_doc/2
{
  "id":"2",
  "content":""
}
POST /index_001/_doc/3
{
  "id":"3",
  "content":"华为电脑"
}
GET /index_001/_search
{
  "query": {
    "match": {
      "content.keyword": "华为电脑"
    }
  }
}

GET /index_001/_mapping
GET /index_001/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "exists": {
            "field": "summary"
          }
        },
        {
          "match": {
            "content": ""
          }
        }
      ]
    }
  }
}

PUT /index_002
GET /index_002/_mapping
POST /index_002/_doc/1
{
  "id":"1",
  "content":"华为手机"
}
POST /index_002/_doc/2
{
  "id":"2",
  "content":""
}
POST /index_002/_doc/3
{
  "id":"3",
  "content":"华为电脑"
}
GET /index_002/_search
{
  "query": {
    "match": {
      "content": "华为"
    }
  }
}
GET /index_002/_search
{
  "query": {
    "match": {
      "content.keyword": "华为电脑"
    }
  }
}
GET /index_002/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "exists": {
            "field": "summary"
          }
        },
        {
          "term": {
            "content.keyword": ""
          }
        }
      ]
    }
  }
}

PUT /index_003/
{
  "mappings": {
    "properties": {
      "id": {
        "type": "keyword"
      },
      "content": {
         "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          },
       "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart"
      }
    }
  }
}
POST /index_003/_analyze
{
  "analyzer": "ik_max_word",
  "text": "华为手机"
}

POST /index_003/_doc/1
{
  "id":"1",
  "content":"华为手机"
}
POST /index_003/_doc/2
{
  "id":"2",
  "content":""
}
POST /index_003/_doc/3
{
  "id":"3",
  "content":"华为电脑"
}
GET /index_003/_search
{
  "query": {
    "match": {
      "content.keyword": "华为电脑"
    }
  }
}
GET /index_003/_search
{
  "query": {
    "term": {
      "content.keyword": "华为"
    }
  }
}
GET /index_003/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "exists": {
            "field": "summary"
          }
        },
        {
          "term": {
            "content.keyword": ""
          }
        }
      ]
    }
  }
}

以上的操作的全部过程,结果如下


image.png
三:坑的由来

在go中content这个字段在解析的时候没有拿到想要的数据,因此采用了默认值,这才出现了上面的问题,因此建议在不确定情况的时候mapping设置成第三种形式最为稳妥,或者字符串的默认值给一个其他的不为空字符串的值即可

上一篇下一篇

猜你喜欢

热点阅读