arrays - Elasticsearch 按数组列排序

标签 arrays ruby sorting elasticsearch

如何使用数字数组按列对记录进行排序? 例如:

[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 做同样的事情?

附言对不起我的英语

最佳答案

在 ElasticSearch 中 arrays of objects do not work as you would expect :

Arrays of objects do not work as you would expect: you cannot query each object independently of the other objects in the array. If you need to be able to do this then you should use the nested datatype instead of the object datatype.

This is explained in more detail in Nested datatype.

不可能在排序时通过索引访问数组元素,因为它们存储在 Lucene 索引中,这基本上只允许 set 操作(“给出具有数组元素 = x 的文档”或“提供没有数组元素 = x 的文档”)。

但是,默认情况下,插入索引的初始 JSON 文档存储在磁盘上,并且可用于字段中的脚本访问 _source .

你有两个选择:

  1. 使用script based sorting
  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 方法,这有利于 denormalization .这里的想法是在将文档插入索引之前进行连接,并使用字符串字段进行稳健排序。

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

希望对您有所帮助!

关于arrays - Elasticsearch 按数组列排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47295552/

相关文章:

ruby - Ruby 中是否有像 C 中那样的 "main"方法?

css - 使用 Compass 函数而不使用 Compass 来编译样式表

java - 我可以将 Collections.sort 与准顺序一起使用吗?

ios - 缺少 Swift 3 数组 indexOf 函数

javascript - 动态过滤嵌套 javascript 对象数组中的数据

在 X-Macro 中打印数组元素时出现编译错误

ruby-on-rails - 如何在同一台机器上使用多个版本的 Rails

python - 一个线性函数,用于根据 python 中的不同条件按升序、降序对列表的字符串列表进行排序

ruby - 用于配对两个数组元素的快速 Ruby 方法/算法

在 C 中复制数组并清除 char 数组中的垃圾