为什么脚本处理器在 reindex api 中工作而不在管道上工作

why script processor works in reindex api and not working on pipeline

我像这样基于 projectId 创建 idices:

//直接调用reindexAPI,效果很好

POST _reindex?wait_for_completion=false
{
  "conflicts": "proceed",
  "source": {
    "index": "xxxxx-rlk-test1-2021-07-22"
  },
  "dest": {
    "index": "xxxxxx",
    "op_type": "create"
  },
  "script": {
    "lang": "painless",
    "source": """
          if (ctx._source.kubernetes != null){
            if (ctx._source.kubernetes.namespace_labels['field_cattle_io/projectId'] != null){
              ctx._index = 'xxxxxx-rlk-'+ (ctx._source.kubernetes.namespace_labels['field_cattle_io/projectId']) + '' + (ctx._index.substring('xxxxxx-rlk-test-'.length(), ctx._index.length()))
            }else {
              ctx._index = 'xxxxxx-rlk-'+ (ctx._source.kubernetes.namespace_labels['field_cattle_io/projectId']) +'-noproject'
            }
          }
      """
  }
}

但是当我想像这样对管道使用重新索引时:

PUT _ingest/pipeline/group-by-projectid-pipeline
{
  "description": "this pipeline split indices by pipeline",
  "processors": [
    {
      "script": {
        "lang": "painless",
        "source": """
          if (ctx.kubernetes != null){
            if (ctx.kubernetes.namespace_labels['field_cattle_io/projectId'] != null){
              ctx._index = 'xxxxxx-rlk-'+ (ctx.kubernetes.namespace_labels['field_cattle_io/projectId']) +'' + (ctx._index.substring('xxxxxx-rlk-test-'.length(), ctx._index.length()))
            }else {
              ctx._index = 'xxxxxx-rlk-'+ (ctx.kubernetes.namespace_labels['field_cattle_io/projectId']) +'-noproject'
            }
          }
      """
      }
    }
  ]
}

和:

POST _reindex
{
  "conflicts": "proceed",
  "source": {
    "index": "xxxxxx-rlk-test1-2021-07-22"
  },
  "dest": {
    "index": "xxxxxx",
    "pipeline": "group-by-projectid-pipeline",
    "op_type": "create"
  }
}

然后 elasticsearch 说(关于 (ctx._index.substring('xxxxxx-rlk-test-'.length(), ctx._index.length()))):

“类型”:“string_index_out_of_bounds_exception”, “原因”:“开始 16,结束 6,长度 6”

提前感谢您的帮助!

这是因为脚本不会在两种情况下同时执行。

在没有管道的重新索引调用期间,脚本在文档到达目标索引之前执行,因此ctx._index是源索引的名称,即xxxxxx-rlk-test1-2021-07-22,因此您的子字符串调用有效。

在使用管道 重新索引调用 期间,脚本处理器在文档即将登陆目标索引时运行,因此 ctx._index 是目标索引,即 xxxxxx.

这就是 '...'.substring(16, 6) 不起作用的原因。所以在第二种情况下你应该采取不同的方式。

解决这个问题的简单方法(如果你想保持相同的逻辑)是使用一个与你应该修改的源索引长度相同的虚拟目标索引:

POST _reindex
{
  "conflicts": "proceed",
  "source": {
    "index": "xxxxxx-rlk-test1-2021-07-22"
  },
  "dest": {
    "index": "xxxxxx-rlk-xxxxx-2021-07-22",        <--- change this
    "pipeline": "group-by-projectid-pipeline",
    "op_type": "create"
  }
}