当前位置: 首页 > 面试题库 >

在Elasticsearch中字段未按字母顺序排序

阳宾实
2023-03-14
问题内容

我有一些带有名称字段的文档。我正在使用名称字段的分析版本进行搜索和not_analyzed排序。排序是在一个级别上进行的,即名称首先是按字母顺序排序的。但是在字母列表中,名称是按字典顺序而不是按字母顺序排序的。这是我使用的映射:

{
  "mappings": {
    "seing": {
      "properties": {
        "name": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        }
      }
    }
  }

谁能提供相同的解决方案?


问题答案:

深入研究Elasticsearch文档,我偶然发现了这一点:

  • 排序和排序规则

不区分大小写的排序

假设我们有三个用户文档,其名称字段分别包含Boffey,BROWN和bailey。首先,我们将应用在字符串排序和多字段中描述的技术,该方法使用not_analyzed字段进行排序:

PUT /my_index
{
  "mappings": {
    "user": {
      "properties": {
        "name": {                    //1
          "type": "string",
          "fields": {
            "raw": {                 //2
              "type":  "string",
              "index": "not_analyzed"
            }
          }
        }
      }
    }
  }
}
  1. analyzed name字段用于搜索。
  2. not_analyzed name.raw字段用于排序。

先前的搜索请求将按以下顺序返回文档:BROWN,Boffey,bailey。与字母顺序相反,这被称为字典顺序。从本质上讲,用于表示大写字母的字节的值比用于表示小写字母的字节的值低,因此,名称以最低的字节排在最前面。

这对计算机可能有意义,但对于合理地期望这些名称按字母顺序(无论大小写)的人类而言,意义不大。为此,我们需要以字节顺序对应于所需排序顺序的方式为每个名称建立索引。

换句话说,我们需要一个可以发出单个小写令牌的分析器:

遵循此逻辑,而不是存储原始文档,您需要使用自定义关键字分析器将其小写:

PUT /my_index
{
  "settings" : {
    "analysis" : {
      "analyzer" : {
        "case_insensitive_sort" : {
          "tokenizer" : "keyword",
          "filter" : ["lowercase"]
        }
      }
    }
  },
  "mappings" : {
    "seing" : {
      "properties" : {
        "name" : {
          "type" : "string",
          "fields" : {
            "raw" : {
              "type" : "string",
              "analyzer" : "case_insensitive_sort"
            }
          }
        }
      }
    }
  }
}

现在,排序依据name.raw应该 按字母 顺序排序,而不是按 字典顺序 排序。

使用Marvel在我的本地计算机上完成的快速测试:

索引结构:

PUT /my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "case_insensitive_sort": {
          "tokenizer": "keyword",
          "filter": [
            "lowercase"
          ]
        }
      }
    }
  },
  "mappings": {
    "user": {
      "properties": {
        "name": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            },
            "keyword": {
              "type": "string",
              "analyzer": "case_insensitive_sort"
            }
          }
        }
      }
    }
  }
}

测试数据:

PUT /my_index/user/1
{
  "name": "Tim"
}

PUT /my_index/user/2
{
  "name": "TOM"
}

使用原始字段查询:

POST /my_index/user/_search
{
  "sort": "name.raw"
}

结果:

{
  "_index" : "my_index",
  "_type" : "user",
  "_id" : "2",
  "_score" : null,
  "_source" : {
    "name" : "TOM"
  },
  "sort" : [
    "TOM"
  ]
},
{
  "_index" : "my_index",
  "_type" : "user",
  "_id" : "1",
  "_score" : null,
  "_source" : {
    "name" : "Tim"
  },
  "sort" : [
    "Tim"
  ]
}

使用小写字符串查询:

POST /my_index/user/_search
{
  "sort": "name.keyword"
}

结果:

{
  "_index" : "my_index",
  "_type" : "user",
  "_id" : "1",
  "_score" : null,
  "_source" : {
    "name" : "Tim"
  },
  "sort" : [
    "tim"
  ]
},
{
  "_index" : "my_index",
  "_type" : "user",
  "_id" : "2",
  "_score" : null,
  "_source" : {
    "name" : "TOM"
  },
  "sort" : [
    "tom"
  ]
}

我怀疑第二个结果在您的情况下是正确的。



 类似资料:
  • 问题内容: 我在Lucene 5.0中对字符串字段进行排序时遇到问题。显然,自Lucene 4更改以来,您可以进行排序的方式。下面显示了正在为我的文档建立索引的某些字段的摘要。 我想首先对相关性进行排序,这很好。我的问题是标题字段上的排序不起作用。我创建了一个排序域,在一系列方法调用之后,我试图将其与TopFieldCollector一起使用。 转到: 最后是应用排序字段的方法: 使用返回的收集器

  • 问题内容: 我是Java的新手,正在尝试按字母顺序排列术语的arrayList。(一个术语定义为一个字符和一个整数)(例如 我的代码如下: 为什么这不起作用?以及我该如何完成呢?我的arrayList称为术语,填充有Term类型 问题答案: 您在这行代码中遇到的问题。您的课程不是So 的类型,这两个对象将基于哪个属性或条件方法? 您必须使您的类为Comparable类型。和,根据您的需要覆盖该方法

  • 问题内容: 如何获得按字段排序的struct输出? 问题答案: A 是字段的 有序 集合。该包使用反射来获取值的字段和值,并按照定义它们的顺序生成输出。 因此,最简单的解决方案是在已经按字母顺序排列字段的位置声明类型: 如果您不能修改字段的顺序(例如,内存布局很重要),则可以通过为结构类型指定一个方法来实现接口: 所述包检查所传递的值工具,并且如果是的话,调用它的方法,以产生输出。 该解决方案的缺

  • 已知字母序列【d, g, e, c, f, b, o, a】,请实现一个函数针对输入的一组字符串 input[] = {“bed”, “dog”, “dear”, “eye”},按照字母顺序排序并打印,结果应为:dear, dog, eye, bed。 说明 本问题在网上比较常见,但这里尝试用另外一个思路,并且用python来写,与众多用c++的有所不同,且似乎短小了不少。自己感觉比网上参考到的更

  • 我想按字段存在对我的ES搜索结果进行排序,假设我得到了字段“价格”,并希望所有有价格的结果都在顶部,所有没有价格的结果都在底部。我知道你可以做一个简单的排序并添加“缺失”:“_last”,例如: {“sort”:[{price':{missing':'u last',order':'asc'}}]} 但在这种情况下,结果也将按价格排序,我不想要它。 没有脚本有办法做到吗?

  • 问题内容: 我得到了一个数组(请参阅下面的数组中的一个对象),我需要使用JavaScript按名字排序。我该怎么做? 问题答案: 假设您有一个数组。您可以使用并传递一个接受两个参数并进行比较的函数(比较器) 它应该返回 如果第一个参数小于第二个参数,则为负数(应在结果数组的第二个参数之前放置) 如果第一个参数较大,则为正数(应放在第二个参数之后) 如果这两个元素相等,则为0。 在我们的情况下,如果