(52)ElasticSearch之字符串排序问题

  1、准备数据

PUT /lib
{
    "settings":{
        "number_of_shards":3,
        "number_of_replicas":0
      },
        "mappings":{
            "user":{
                "properties":{
                    "name":{"type":"text"},
                    "address":{"type":"text"},
                    "age":{"type":"integer"},
                    "interests":{"type":"text"},
                    "birthday":{"type":"date"}
                }
            }
        }
}
put /lib/user/1
{
    "name":"zhaoliu",
    "address":"hei long jiang sheng tie ling shi",
    "age":50,
    "birthday":"1970-12-12",
    "interests":"xi huang hejiu,duanlian,lvyou"
}

put /lib/user/2
{
    "name":"zhaoming",
    "address":"bei jing hai dian qu qing he zhen",
    "age":20,
    "birthday":"1998-10-12",
    "interests":"xi huan hejiu,duanlian,changge"
}

put /lib/user/3
{
    "name":"lisi",
    "address":"bei jing hai dian qu qing he zhen",
    "age":23,
    "birthday":"1998-10-12",
    "interests":"xi huan hejiu,duanlian,changge"
}

put /lib/user/4
{
    "name":"wangwu",
    "address":"bei jing hai dian qu qing he zhen",
    "age":26,
    "birthday":"1998-10-12",
    "interests":"xi huan biancheng,tingyinyue,lvyou"
}

put /lib/user/5
{
    "name":"zhangsan",
    "address":"bei jing chao yang qu",
    "age":29,
    "birthday":"1988-10-12",
    "interests":"xi huan tingyinyue,changge,tiaowu"
}

  2、操作演示

  1)按照年龄降序排序

GET lib/user/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ]
}

  查询结果

{
  "took": 42,
  "timed_out": false,
  "_shards": {
    "total": 3,
    "successful": 3,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 5,
    "max_score": null,
    "hits": [
      {
        "_index": "lib",
        "_type": "user",
        "_id": "1",
        "_score": null,
        "_source": {
          "name": "zhaoliu",
          "address": "hei long jiang sheng tie ling shi",
          "age": 50,
          "birthday": "1970-12-12",
          "interests": "xi huang hejiu,duanlian,lvyou"
        },
        "sort": [
          50
        ]
      },
      {
        "_index": "lib",
        "_type": "user",
        "_id": "5",
        "_score": null,
        "_source": {
          "name": "zhangsan",
          "address": "bei jing chao yang qu",
          "age": 29,
          "birthday": "1988-10-12",
          "interests": "xi huan tingyinyue,changge,tiaowu"
        },
        "sort": [
          29
        ]
      },
      {
        "_index": "lib",
        "_type": "user",
        "_id": "4",
        "_score": null,
        "_source": {
          "name": "wangwu",
          "address": "bei jing hai dian qu qing he zhen",
          "age": 26,
          "birthday": "1998-10-12",
          "interests": "xi huan biancheng,tingyinyue,lvyou"
        },
        "sort": [
          26
        ]
      },
      {
        "_index": "lib",
        "_type": "user",
        "_id": "3",
        "_score": null,
        "_source": {
          "name": "lisi",
          "address": "bei jing hai dian qu qing he zhen",
          "age": 23,
          "birthday": "1998-10-12",
          "interests": "xi huan hejiu,duanlian,changge"
        },
        "sort": [
          23
        ]
      },
      {
        "_index": "lib",
        "_type": "user",
        "_id": "2",
        "_score": null,
        "_source": {
          "name": "zhaoming",
          "address": "bei jing hai dian qu qing he zhen",
          "age": 20,
          "birthday": "1998-10-12",
          "interests": "xi huan hejiu,duanlian,changge"
        },
        "sort": [
          20
        ]
      }
    ]
  }
}

  因为age是数值类型的,所以可以排序,默认字符串类型的不能排序,因为字符串类型的已经分词了。如下根据interests排序会报错:

GET lib/user/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "interests": {
        "order": "desc"
      }
    }
  ]
}
{
  "error": {
    "root_cause": [
      {
        "type": "illegal_argument_exception",
        "reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [interests] 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": "lib",
        "node": "AJ3x6yc8TfKj6_zx6VRm0g",
        "reason": {
          "type": "illegal_argument_exception",
          "reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [interests] 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
}

  3、如何对字符串类型的排序

  对一个字符串类型的字段进行排序通常不准确,因为已经被分词成多个词条了。

  解决方式:对字段索引两次,一次索引分词(用于搜索),一次索引不分词(用于排序)

  1)删掉上面的lib索引,重新创建,修改 interests 字段的创建方式,并重新添加如上数据

PUT /lib
{
    "settings":{
        "number_of_shards":3,
        "number_of_replicas":0
      },
        "mappings":{
            "user":{
                "properties":{
                    "name":{"type":"text"},
                    "address":{"type":"text"},
                    "age":{"type":"integer"},
                    "interests":{
                      "type":"text",
                      "fields": {
                        "raw":{
                          "type": "keyword"
                        }
                      },
                      "fielddata": true
                    },
                    "birthday":{"type":"date"}
                }
            }
        }
}

  字符串有两种类型,一种是text,默认分词,一种是keyword不分词,interests创建两种类型的索引,一种text(倒排索引),一个keyword(正排索引)。

  重新执行操作,返回正确结果:

GET lib/user/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "interests.raw": {
        "order": "desc"
      }
    }
  ]
}
{
  "took": 6,
  "timed_out": false,
  "_shards": {
    "total": 3,
    "successful": 3,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 5,
    "max_score": null,
    "hits": [
      {
        "_index": "lib",
        "_type": "user",
        "_id": "1",
        "_score": null,
        "_source": {
          "name": "zhaoliu",
          "address": "hei long jiang sheng tie ling shi",
          "age": 50,
          "birthday": "1970-12-12",
          "interests": "xi huang hejiu,duanlian,lvyou"
        },
        "sort": [
          "xi huang hejiu,duanlian,lvyou"
        ]
      },
      {
        "_index": "lib",
        "_type": "user",
        "_id": "5",
        "_score": null,
        "_source": {
          "name": "zhangsan",
          "address": "bei jing chao yang qu",
          "age": 29,
          "birthday": "1988-10-12",
          "interests": "xi huan tingyinyue,changge,tiaowu"
        },
        "sort": [
          "xi huan tingyinyue,changge,tiaowu"
        ]
      },
      {
        "_index": "lib",
        "_type": "user",
        "_id": "2",
        "_score": null,
        "_source": {
          "name": "zhaoming",
          "address": "bei jing hai dian qu qing he zhen",
          "age": 20,
          "birthday": "1998-10-12",
          "interests": "xi huan hejiu,duanlian,changge"
        },
        "sort": [
          "xi huan hejiu,duanlian,changge"
        ]
      },
      {
        "_index": "lib",
        "_type": "user",
        "_id": "3",
        "_score": null,
        "_source": {
          "name": "lisi",
          "address": "bei jing hai dian qu qing he zhen",
          "age": 23,
          "birthday": "1998-10-12",
          "interests": "xi huan hejiu,duanlian,changge"
        },
        "sort": [
          "xi huan hejiu,duanlian,changge"
        ]
      },
      {
        "_index": "lib",
        "_type": "user",
        "_id": "4",
        "_score": null,
        "_source": {
          "name": "wangwu",
          "address": "bei jing hai dian qu qing he zhen",
          "age": 26,
          "birthday": "1998-10-12",
          "interests": "xi huan biancheng,tingyinyue,lvyou"
        },
        "sort": [
          "xi huan biancheng,tingyinyue,lvyou"
        ]
      }
    ]
  }
}
原文地址:https://www.cnblogs.com/javasl/p/12660297.html