当前位置: 首页 > 知识库问答 >
问题:

如何在AWS ElasticSearch的无痛内联脚本中替换字符串而不使用regexp?

湛光华
2023-03-14

文档中“level”字段的类型从“keyword”更改为“short ”,我正在尝试重新索引现有数据,以便能够在Kibana图表中使用它。旧数据包含类似“100%”、“错误”或空字符串“”的值。

我只想在新索引中获取整数。我使用内部重新索引API(添加新行以使代码段更具可读性):

curl -s -X POST -H 'Content-Type: application/json' https://search-host.us-east-1.es.amazonaws.com/_reindex -d '{
  "source": {
    "index": "old-index"
  },  
  "dest": {
    "index": "new-index"
  },  
  "script": {
    "inline": "
        if (ctx._source.level == \"error\" || ctx._source.level == \"\")
        {
            ctx._source.level = -1
        } else {
            ctx._source.level = Integer.valueOf(ctx._source.level)    )
        }
    "
  }
}'

但是我得到了一个错误:“java.lang.String不能转换为java.lang.Number”,因为在值的末尾有一个“%”符号。

此外,我没有为AWS ElasticSearch启用正则表达式,也不可能像我想的那样。因此,带有replaceAll的变体对我不起作用。例如,如果我有自托管ES,它可能是这样的(没有测试):/(%)?/。匹配器(doc['level].value)。replaceAll('$1')

但从AWS ES中我看到:

Regexes are disabled. Set [script.painless.regex.enabled] to [true] in elasticsearch.yaml to allow them. Be careful though, regexes break out of Painless's protection against deep recursion and long loops.

是否可以在没有正则表达式的情况下用无痛语言替换字符串?

共有2个答案

蒋栋
2023-03-14

我试图做同样的事情,我最终会在我的一个索引的字符串字段中进行完整的查找和替换。不幸的是,对我来说也是如此,我无法访问正则表达式。

这是我提出的解决方案,使用了如下的摄取管道:

PUT _ingest/pipeline/my-pipeline-id
{
    "description": "Used to update in place",
    "processors": [
        {
            "grok": {
                "field": "myField",
                "patterns": ["%{PART1:field1}%{REMOVAL}%{PART2:field2}"],
                "pattern_definitions": {
                    "PART1": "start",
                    "REMOVAL": "(toRemove){0,1}",
                    "PART2": ".+"
                },
                "ignore_missing": true
            }
        },
        {
            "script": {
                "lang": "painless",
                "inline": "ctx.myField = ctx.field1 + ctx.field2"
            }
        },
        {
            "script": {
                "lang": "painless",
                "inline": "ctx.remove('field1'); ctx.remove('field2')"
            }
        }
    ]
}

然后运行它(我已经用查询更新过了)

POST /index/type/_update_by_query?pipeline=my-pipeline-id
{
    "query": {
        "match": {
            "id": "123456789"
        }
    }
}
    < li>Grok调试器 < li>Grok处理器 < li >通过查询API更新 < li >如何使用Logstash Grok过滤器提取模式

我使用的是ES 5.5。版本6的一些语法已更改,但过程保持不变。

施恩
2023-03-14
"script": {
    "lang":"painless",
    "source": """

      //function declaration
      String replace(String word, String oldValue, String newValue) {
        String[] pieces = word.splitOnToken(oldValue);
        int lastElIndex = pieces.length-1;
        pieces[lastElIndex] = newValue;
        def list = Arrays.asList(pieces);
        return String.join('',list);
      }

      //usage sample
      ctx._source["date"] = replace(ctx._source["date"],"+0000","Z");

    """
}
 类似资料:
  • 在Elasticsearch 6.2中,我有一个索引,其中有两个时间戳字段,如下所示: 在我无痛的内联脚本中,对于一些计算,我想将它们(和)转换为此字符串格式()。任何想法怎么能做到?我无法在ES官方文档中找到任何格式化文档。

  • 问题内容: 在Python中,什么时候以及什么时候使用字符串连接与字符串替换比较容易。由于字符串连接的性能有了很大的提高,这(成为更多)是一种风格上的决定,而不是一种实际的决定吗? 举一个具体的例子,如何处理灵活的URI: 编辑:也有关于加入字符串列表和使用命名替换的建议。这些是中心主题的变体,即在什么时候做正确的方法?感谢您的回复! 问题答案: 根据我的机器,连接的速度(明显)更快。但是从风格上

  • 问题内容: 我的桌子上有一个方程式。我一次要提取一个方程式,并希望将所有运算符替换为其他任何字符。 输入字符串: 运算符或模式: 替换字符: 输出字符串: 我曾尝试使用 嵌套的REPLACE 函数在下面的查询中得到所需的输出: 输出: 如何在不使用嵌套替换功能的情况下替换所有运算符? 问题答案: 我创建了一个函数来实现此目的,因为我需要多次执行此操作 分割功能 过程中使用的代码: 输出

  • 问题内容: 我刚开始使用ES,但仍然喜欢交易的技巧!!!我需要替换/覆盖嵌套对象类型的字段之一。这是示例文档: 映射以上文档: 我需要更新给定ref_name的计数字段值。例如,在上述情况下,如果 ref_name 是“ test1 ”,我希望新 计数 为 500 。我想出了下面的简单 脚本 来更改 计 数值,它可以正常执行而没有任何错误,但是我看不到该值正在更新。 以下是响应: 但是,当我看到该

  • 问题内容: 我试图遍历一个字符数组,并将字符串中的该字符替换为另一个数组中的并行字符。 这是我得到的例子: 它总是输出相同的字符串,没有替换。 我也尝试使用: 和replaceAll方法。 有什么建议? 问题答案: 字符串在Java中是不可变的。不会 更改 您调用它的字符串-它会 返回 更改后的新字符串。所以你要: (对于要在其上“显示”更改的 所有 方法,这都是不变的,因此也是如此。)

  • 像这样的空字符串isnull()找不到空字符串