嵌套中的Elasticsearch更新日期

时间:2019-02-14 10:43:16

标签: elasticsearch

我想从历史记录中的所有日期中删除15分钟,这些日期都少于15分钟。

所以我必须现在比较日期-与记录日期相差15分钟。

但是,当我检索日期时,它无法比较它,因为它就像一个字符串,并且添加“ .value”会返回该属性不存在。

错误响应:

"if(ctx._source.histories[i].creation_date.value"
dynamic getter [java.lang.String, value] not found

尝试其他解决方案时出错:

"if(ctx._source.histories[i].creation_date.date"
"if(ctx._source.histories[i].creation_date.getMillis()"
"if(ctx._source.histories[i].creation_date.value.getMillis()"

更新请求(elasticsearch.js):

{
    "query": { "term": { "user_id": "USER_ID" } },
    "script":
    {
        "lang":   "painless",
        "source": "for(int i = ctx._source.histories.length-1; i > 0; --i){ if(ctx._source.histories[i].creation_date.value > params.date) { ctx._source.histories[i].creation_date -= 1000 * 60 * 15; } }",
        "params": { "date": new Date() - 1000 * 60 * 15 }
    }
}

映射:

{
  "mappings":
  {
    "_doc":
    {
      "properties":
      {
        "histories":
        {
          "type": "nested",
          "properties":
          {
            "type":          { "type": "text" },
            "key":           { "type": "text" },
            "value":         { "type": "text" },
            "ip":            { "type": "ip" },
            "useragent":     { "type": "text" },
            "creation_date": { "type": "date" }
          }
        }
      }
    }
  }
}

信息弹性搜索:

{
  "name" : "ZZZ",
  "cluster_name" : "YYY",
  "cluster_uuid" : "XXX",
  "version" : {
    "number" : "6.5.2",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "WWW",
    "build_date" : "2018-11-29T23:58:20.891072Z",
    "build_snapshot" : false,
    "lucene_version" : "7.5.0",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

示例数据:

{
  "hits":
  {
    "total": 1,
    "max_score": 4.13468,
    "hits":
    [
      {
        "_index": "myindex",
        "_type": "_doc",
        "_id": "H1dQ4WgBypYasGfnnXXI",
        "_score": 4.13468,
        "_source":
        {
          "infos":
          {
            "firsname": "John",
            "lastname": "Doe",
            "mail": "john.doe@stackoverflow.com"
          },
          "histories":
          [
            {
                    "type":          "auth",
                    "key":           "try",
                    "value":         "fail",
                    "ip":            "127.0.0.1",
                    "useragent":     "iPhoneX",
                    "creation_date": "2019-02-19T16:49:00.396Z"
            },
            {
                    "type":          "auth",
                    "key":           "try",
                    "value":         "fail",
                    "ip":            "127.0.0.1",
                    "useragent":     "iPhoneX",
                    "creation_date": "2019-02-19T16:50:00.396Z"
            }
          ]
        }
      }
    ]
  }
}

1 个答案:

答案 0 :(得分:2)

我认为我可能会有所帮助(在ES 6.6.0上测试)。

{
  "query": {
    "match_all": {}
  },
  "script": {
    "lang": "painless",
    "source": """
    // parse params.data to Instant
    def paramDate = Instant.parse(params.date);

    for(int i = ctx._source.histories.length-1; i > 0; --i) { 
      // parse the creation date to Instant
      def creationDate = Instant.parse(ctx._source.histories[i].creation_date);

      // check time difference between both
      if (ChronoUnit.MINUTES.between(creationDate, paramDate) <= 15) {
        // remove 15 minutes if condition satisfied
        ctx._source.histories[i].creation_date = creationDate.minusSeconds(900).toString(); 
      } 
    }
    """,
    "params": {
      "date": "2019-02-19T16:45:00.000Z"
    }
  }
}

注意:我使用三引号使查询更具可读性,但是请在您认为合适的时候再次对其进行内联并删除注释。