Elasticsearch按数组列排序

4
如何按带有数字数组的列对记录进行排序? 例如:
[1, 32, 26, 16]
[1, 32, 10, 1500]
[1, 32, 1,  16]
[1, 32, 2,  17]

预期的结果是:
[1, 32, 1,  16]
[1, 32, 2,  17]
[1, 32, 10, 1500]
[1, 32, 26, 16]

Elasticsearch有排序模式选项:https://www.elastic.co/guide/en/elasticsearch/reference/1.4/search-request-sort.html#_sort_mode_option。但是没有一个变量是适当的。
Ruby语言可以对数字数组进行排序,Ruby有方法Array.<=>,其描述为“比较每个数组中的每个对象”。
如何在elasticsearch中实现相同的功能?
附言:对不起我的英语。
1个回答

2
在ElasticSearch中,对象数组不像你期望的那样工作

对象数组不像你期望的那样工作:你不能查询数组中每个对象而不独立于数组中的其他对象。如果需要这样做,则应使用嵌套数据类型而不是对象数据类型。

这在嵌套数据类型中有更详细的解释。

由于它们存储在Lucene索引中,因此无法按其索引在排序时访问数组元素,该索引基本上只允许set操作(“给出具有数组元素=x的文档”或“给出没有数组元素=x的文档”)。
然而,默认情况下插入索引的初始JSON文档存储在磁盘上,并且可以在字段_source中进行脚本访问。
你有两个选择:
  1. 使用基于脚本的排序
  2. 将排序值显式存储为字符串
让我们稍微详细地讨论这些选项。

1. 基于脚本的排序

第一个选项更像是一种hack。假设您有以下映射:
PUT my_index
{
  "mappings": {
    "my_type": {
      "properties": {
        "my_array": {
          "type": "integer"
        }
      }
    }
  }
}

然后,您可以通过脚本排序来实现预期的行为:

POST my_index/my_type/_search
{
      "sort" : {
        "_script" : {
            "script" : "String s = ''; for(int i = 0; i < params._source.my_array.length; ++i) {s += params._source.my_array[i] + ','}  s",
            "type" : "string",
            "order" : "asc"
        }
    }
}

我将为您翻译这段内容。这是关于编程的,作者在 ElasticSearch 5.4 上测试了代码,并相信较早版本也有类似的功能。如果您需要早期版本的信息,请参阅相关文档,例如1.4。输出结果将如下:
  "hits": {
    "total": 2,
    "max_score": null,
    "hits": [
      {
        "_index": "my_index",
        "_type": "my_type",
        "_id": "2",
        "_score": null,
        "_source": {
          "my_array": [
            1,
            32,
            1,
            16
          ]
        },
        "sort": [
          "1,32,1,16,"
        ]
      },
      {
        "_index": "my_index",
        "_type": "my_type",
        "_id": "1",
        "_score": null,
        "_source": {
          "my_array": [
            1,
            32,
            10,
            1500
          ]
        },
        "sort": [
          "1,32,10,1500,"
        ]
      }
    ]   }

请注意,此解决方案将会很慢且占用内存,因为它需要从磁盘中读取_source中所有文档的排序,并将它们加载到内存中。

2. 去规范化

将排序值作为字符串显式存储更像是 ElasticSearch 的方法,它更青睐去规范化。在这里,想法是在将文档插入索引之前进行串联,并使用强大的字符串字段进行排序。

请根据您的需求选择更合适的解决方案。

希望这有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接