【问题标题】:Painless access a value in an ArrayList无痛访问 ArrayList 中的值
【发布时间】:2020-04-19 08:26:10
【问题描述】:

试图弄清楚如何访问 ArrayList 中的项目。

我有 _source 中的值:

  "session_id" : [
    "19a7ec8d",
    "19a7ec8d"
  ],

由于它们都是重复的(由于 Grok 脚本错误),我想摆脱重复:

我无法确定如何访问该值。

String old = ctx._source.session_id[0];
ctx._source.remove(\"session_id\");
ctx._source.session_id = old;

我也试过了:

String old = ctx._source.session_id.get(0);

String old = ctx._source.session_id.get(0).value()

String old = ctx._source.session_id[0].value()

String old = ctx._source.session_id.get(0).toString()

谢谢

【问题讨论】:

    标签: elasticsearch elasticsearch-painless


    【解决方案1】:

    您可以使用_update_by_query

    数据:

    "hits" : [
          {
            "_index" : "index7",
            "_type" : "_doc",
            "_id" : "zQPYkXEB9JyZpSui0FLw",
            "_score" : 1.0,
            "_source" : {
              "session_id" : [
                "19a7ec8d",
                "19a7ec8d"
              ]
            }
          }
        ]
    

    查询:

    POST index7/_update_by_query
    {
      "script":{
        "source":"if(ctx._source.session_id instanceof List && ctx._source.session_id.size()>0) { def firstValue=ctx._source.session_id[0];ctx._source.session_id=firstValue;}"
      },
      "query":{
        "match_all":{} 
      }
    }
    

    结果:

    "hits" : [
          {
            "_index" : "index7",
            "_type" : "_doc",
            "_id" : "zQPYkXEB9JyZpSui0FLw",
            "_score" : 1.0,
            "_source" : {
              "session_id" : "19a7ec8d"
            }
          }
        ]
    

    【讨论】:

    • 谢谢。我得到以下信息: ''"reason" : "dynamic method [java.lang.String, size/0] not found"'' 带有指向 .在 session_id.size()
    • 你能添加一个示例文档和你的映射吗
    • 使用您的方法,这似乎有效... "if(!(ctx._source.session_id instanceof List)) {return;} def firstValue=ctx._source.session_id[0];ctx ._source.session_id=firstValue"
    • 以前我试图只过滤匹配的文档:ctx._source.session_id instanceof List - 我认为它返回的文档也不匹配。
    • 无法过滤查询中的大小。根据discuss.elastic.co/t/duplicate-value-in-a-fileds/198936/8。 “这是对大型数据集的预期。不用担心,查询更新将继续在后台运行,直到处理完所有数据”。你能在一段时间后检查字段是否更新
    【解决方案2】:

    一种使数组项唯一的通用方法:

    GET index7/_update_by_query
    {
      "query": {
        "bool": {
          "filter": {
            "exists": {
              "field": "session_id"
            }
          }
        }
      },
      "script": {
        "inline": """ctx._source.session_id = ctx._source
                                                .session_id
                                                .stream()
                                                .sorted()
                                                .collect(Collectors.toList());
                                                """
      }
    }
    

    【讨论】:

    • 谢谢,这很有帮助。如果这仅导致一项,这是否仍将其保留为包含一项的列表,还是将其转换为一个值?
    • toList() 会保留一个列表。如果你想让它保持单值,你可以在上面做[0]。公平地说,这种重复数据删除方法是为[1,2,2,3,3]...等情况而设计的。
    猜你喜欢
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-06
    • 2018-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多