elasticsearch学习笔记二十九Elasticsearch-将一个field索引两次来解决字符串排序问题

49次阅读

共计 2378 个字符,预计需要花费 6 分钟才能阅读完成。

下面描述一个场景

如果某个字段的类型是 text,在创建索引的时候,针对每个 document,对应的这个 text 字段都会对内容进行分词。由于 ES 不允许对已经存在的 field 的类型进行修改,就会导致该字段一直都是会被分词,那么如果之后有需求想对该字段排序,就不行了。具体看下面展示的示例。

PUT /test_index
{
  "mappings": {
    "properties": {
      "field1": {"type": "text"}
    }
  }
}
GET /test_index/_search
{
  "query": {"match_all": {}
  },
  "sort": [
    {
      "field1": {"order": "desc"}
    }
  ]
}
{
  "error": {
    "root_cause": [
      {
        "type": "illegal_argument_exception",
        "reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [field1] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."
      }
    ],
    "type": "search_phase_execution_exception",
    "reason": "all shards failed",
    "phase": "query",
    "grouped": true,
    "failed_shards": [
      {
        "shard": 0,
        "index": "test_index",
        "node": "P-b-TEvyQOylMyEcMEhApQ",
        "reason": {
          "type": "illegal_argument_exception",
          "reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [field1] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."
        }
      }
    ],
    "caused_by": {
      "type": "illegal_argument_exception",
      "reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [field1] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.",
      "caused_by": {
        "type": "illegal_argument_exception",
        "reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [field1] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."
      }
    }
  },
  "status": 400
}

这个时候要想解决这个问题,就可以将一个 string field 建立两次索引,一个分词用来搜索,一个不分词用来进行排序。
Alternatively use a keyword field instead.
根据错误中的提示,我们重新建立索引

PUT /test_index
{
  "mappings": {
    "properties": {
      "field1": {
        "type": "text",
        "fields": {
          "keyword": {"type": "keyword"}
        }
      }
    }
  }
}

GET /test_index/_search
{
  "query": {"match_all": {}
  },
  "sort": [
    {
      "field1.keyword": {"order": "desc"}
    }
  ]
}

{
  "took" : 6,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : null,
        "_source" : {"field1" : "third"},
        "sort" : ["third"]
      },
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : null,
        "_source" : {"field1" : "second"},
        "sort" : ["second"]
      },
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : null,
        "_source" : {"field1" : "one"},
        "sort" : ["one"]
      }
    ]
  }
}

正文完
 0