【问题标题】:How to generate a UUID in Elasticsearch reindex painless script如何在 Elasticsearch reindex 无痛脚本中生成 UUID
【发布时间】:2019-02-14 02:20:55
【问题描述】:

我正在尝试使用 reindex api 创建一组文档的副本。文档的字段之一 (uuid) 是 UUID。我需要复制的文档为uuid 字段设置新的 UUID。

根据 [1] 和 [2],方法 java.util.UUID.randomUUID() 未列入白名单以用于无痛脚本。

问题:

1) 如何在无痛中生成 UUID?

2) 为什么UUID.randomUUID() 被认为是不安全的操作?还是它没有被列入白名单只是一个疏忽?

3) 如何在"reindex" 上下文中将UUID.randomUUID() 列入白名单?我尝试根据 [3] 中的示例构建自己的 elasticsearch 无痛扩展/插件来执行此操作。问题是它只适用于"SearchScript" 上下文。似乎没有等效的"ReindexContext"

这是我正在尝试的简化版本:

curl -X POST "localhost:9200/_reindex?pretty" -H 'Content-Type: application/json' -d'
{
  "source": {
    "index": "product1"
  },
  "dest": {
    "index": "product2"
  },
  "script": {
    "source": "ctx._source.uuid = java.util.UUID.randomUUID().toString()",
    "lang": "painless"
  }
}
'

这会产生以下错误:

{
  "error" : {
    "root_cause" : [
      {
        "type" : "script_exception",
        "reason" : "compile error",
        "script_stack" : [
          "... rce.uuid = java.util.UUID.randomUUID().toString()",
          "                             ^---- HERE"
        ],
        "script" : "ctx._source.uuid = java.util.UUID.randomUUID().toString()",
        "lang" : "painless"
      }
    ],
    "type" : "script_exception",
    "reason" : "compile error",
    "script_stack" : [
      "... rce.uuid = java.util.UUID.randomUUID().toString()",
      "                             ^---- HERE"
    ],
    "script" : "ctx._source.uuid = java.util.UUID.randomUUID().toString()",
    "lang" : "painless",
    "caused_by" : {
      "type" : "illegal_argument_exception",
      "reason" : "method [java.util.UUID, randomUUID/0] not found"
    }
  },
  "status" : 500
}

我知道我的方法是有效的,并且上述是一个轻松的白名单问题,因为当我尝试不同的方法 (fromString()) 时,我没有收到任何错误:

curl -X POST "localhost:9200/_reindex?pretty" -H 'Content-Type: application/json' -d'
{
  "source": {
    "index": "product1"
  },
  "dest": {
    "index": "product2"
  },
  "script": {
    "source": "ctx._source.uuid = java.util.UUID.fromString(\u0027ad139caa-5b54-4179-b812-5015daecad1e\u0027).toString()",
    "lang": "painless"
  }
}
'

参考文献:

[1] - https://discuss.elastic.co/t/generate-a-uuid-using-randomuuid-in-painless/144354/3

[2] - https://www.elastic.co/guide/en/elasticsearch/painless/6.6/painless-api-reference.html

[3] - https://github.com/elastic/elasticsearch/tree/v6.6.0/plugins/examples/painless-whitelist

其他说明:

【问题讨论】:

  • 可以在脚本中定义您自己的自定义实现/方法,以根据您的要求生成 uuid 并使用该方法。基本上,解决依赖关系
  • 我解决此问题的功能请求已在此处接受并实施:github.com/elastic/elasticsearch/issues/39080

标签: elasticsearch elasticsearch-painless


【解决方案1】:

我解决此问题的功能请求已在此处接受并实施:https://github.com/elastic/elasticsearch/issues/39080

【讨论】:

    【解决方案2】:
    You can simply do the following,
    
    curl -X POST "localhost:9200/_reindex?pretty" -H 'Content-Type: application/json' -d'
    {
      "source": {
        "index": "product1"`enter code here`
      },
      "dest": {
        "index": "product2"
      },
      "script": {
        "source": "ctx._id=ctx._id+1",
        "lang": "painless"
      }
    }
    '
    ctx._id = will always give you a new id and plus 1 will generate the new one.
    

    这只是通过添加后缀来获得唯一ID的解决方案

    【讨论】:

    • 感谢您的回答。但是,问题是关于更新 uuid 字段,结果需要是有效的 uuid。
    【解决方案3】:

    最直接的方法是使用自己编写的函数,这是我的。当然,这只是一种解决方法,但在大多数情况下应该会有所帮助。

    String generateUUID(boolean addDashes, boolean upperCase) {
        def chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
    
        def dashIndices = [7, 11, 15, 19];
    
        def sb = new StringBuilder();
    
        def r = new Random();
    
        for (def pos = 0; pos < 32; pos += 1) {
           sb.append(chars[r.nextInt(16)]);
    
           if (addDashes && dashIndices.contains(pos)) {
             sb.append('-');
           }
        }
    
        def result = sb.toString();
    
        return upperCase ? result.toUpperCase() : result;
    }
    

    将其复制到您的脚本中,如果您需要带有破折号和小写字母的 UUID,您将能够通过调用例如 generateUUID(true, false) 来获取 UUID。

    【讨论】:

    • 我解决此问题的功能请求已在此处接受并实施:github.com/elastic/elasticsearch/issues/39080
    • @OliverHenlich 干得好!很高兴知道 Painless 在不久的将来会变得不那么痛苦。
    • 如果您确实像这样生成自己的随机 UUID,请务必设置适当的位以将其标记为 random UUID。请参阅:tools.ietf.org/html/rfc4122 第 4.4 节。
    猜你喜欢
    • 2022-07-06
    • 2017-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-09
    • 1970-01-01
    • 1970-01-01
    • 2022-08-09
    相关资源
    最近更新 更多