elasticsearch學習筆記(二十九)——Elasticsearch 將一個field索引兩次來解決字符串排序問題

下面描述一個場景

若是某個字段的類型是text,在建立索引的時候,針對每一個document,對應的這個text字段都會對內容進行分詞。因爲ES不容許對已經存在的field的類型進行修改,就會致使該字段一直都是會被分詞,那麼若是以後有需求想對該字段排序,就不行了。具體看下面展現的示例。node

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.
根據錯誤中的提示,咱們從新創建索引app

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"
        ]
      }
    ]
  }
}
相關文章
相關標籤/搜索