0

我想创建一个脚本字段来检查嵌套字段的两个属性。

我有一个 ES 索引,其中包含有关进程的信息。一个进程被配置为一个嵌套对象。每个文档可以有多个进程。也可以有多个相同类型的进程(相同的processDefinitionKey)。

这就是目前流程的结构:

"process" : {
  "type" : "nested",
  "include_in_parent" : true,
  "properties" : {
    "created" : {
      "type" : "date",
      "format" : "date_optional_time"
    },
    "ended" : {
      "type" : "date",
      "format" : "date_optional_time"
    },
    "id" : {
      "type" : "text",
      "index" : false
    },
    "processDefinitionKey" : {
      "type" : "keyword"
    },
    "processDefinitionName" : {
      "type" : "text",
      "fields" : {
        "raw" : {
          "type" : "keyword",
          "index" : false
        }
      },
      "analyzer" : "case_insensitive_sort"
    }
  }
}

现在我对特定类型的所有活动过程感兴趣。所以他们必须有一个特定的processDefinitionKey并且还不能有一个ended属性。我为它写了一个 ES 查询:

{
  "query": {
    "nested": {
      "path": "process",
      "query": {
        "bool": {
          "must": {
            "match": {
              "process.processDefinitionKey": "service_agreement"
            }
          },
          "must_not": {
            "exists": {
              "field": "process.ended"
            }
          }
        }
      }
    }
  }
}

我已将此查询添加为可在 Kibana 仪表板上使用的过滤器。我认为它应该起作用。

但是,我更愿意通过为其创建脚本字段来将此属性“具有此类活动进程”添加为搜索表中的一列。这是我到目前为止提出的脚本字段(在无痛中):

doc['process.processDefinitionKey'].contains('service_agreement') && doc['process.ended'].empty

但是这里的结果与上面的查询不一致。恐怕这个脚本会检查是否存在正确processDefinitionKey进程和没有属性的进程。ended但它不会检查两个属性对于同一进程是否为真。

如何确保脚本化字段同时检查同一进程processDefinitionKey的属性和属性?ended

我使用 Kibana 6.4.2

编辑:

脚本字段应返回的文档示例true(service_agreement 进程尚未结束,其他进程已结束):

{
  "_index": ...,
  "_type"...,
  "_id": ...,
  "_version": ...,
  "_score": ...,
  "_source": {
    "type": ...,
    ...,
    "process": [
      {
        "id": "130707",
        "created": "2017-09-11T09:50:52.000+02:00",
        "ended": "2017-09-13T10:16:43.000+02:00",
        "processDefinitionKey": "so_ondertekenproces",
        "processDefinitionName": "Samenwerkingsovereenkomst",
        "incidents": []
      },
      {
        "id": "c2a83c07-15f7-11e7-a20e-0242ac120004",
        "created": "2017-03-31T11:52:32.000+02:00",
        "processDefinitionKey": "service_agreement",
        "processDefinitionName": "Service Agreement",
        "incidents": []
      }
    ]
  },
  "fields": {
    "process.created": [
      "2017-03-31T09:52:32.000Z",
      "2017-09-11T07:50:52.000Z"
    ],
    "process.ended": [
      "2017-09-13T08:16:43.000Z"
    ]
  }
}

脚本字段应返回的文档示例false

{
  "_index": ...,
  "_type": ...,
  "_id": ...,
  "_score": ...,
  "_source": {
    "type": ...,
    ...,
    "process": [
      {
        "id": "17154",
        "created": "2017-05-24T13:21:40.000+02:00",
        "ended": "2017-05-24T13:23:24.000+02:00",
        "processDefinitionKey": "so_ondertekenproces",
        "processDefinitionName": "Samenwerkingsovereenkomst",
        "incidents": []
      },
      {
        "id": "17263",
        "created": "2017-05-24T13:23:29.000+02:00",
        "ended": "2017-09-27T14:31:00.000+02:00",
        "processDefinitionKey": "so_ondertekenproces",
        "processDefinitionName": "Samenwerkingsovereenkomst",
        "incidents": []
      },
      {
        "id": "f1cd056e-15f7-11e7-a20e-0242ac120004",
        "created": "2017-03-31T11:53:51.000+02:00",
        "ended": "2017-10-10T11:35:47.000+02:00",
        "processDefinitionKey": "service_agreement",
        "processDefinitionName": "Service Agreement",
        "incidents": []
      }
    ]
  },
  "fields": {
    "process.created": [
      "2017-03-31T09:53:51.000Z",
      "2017-05-24T11:21:40.000Z",
      "2017-05-24T11:23:29.000Z"
    ],
    "process.ended": [
      "2017-05-24T11:23:24.000Z",
      "2017-09-27T12:31:00.000Z",
      "2017-10-10T09:35:47.000Z"
    ]
  }
}
4

1 回答 1

1

在这里,您正在处理嵌套文档。因此,您需要遍历嵌套文档并评估所需条件是否匹配。这可以使用以下脚本来实现:

更新答案:

boolean res = false;
for(int i = 0; i < params['_source']['process'].length; i++) {
   if(params['_source']['process'][i]['processDefinitionKey'] == 'service_agreement' && !params['_source']['process'][i].containsKey('ended')) {
      res = true;
      break;
   }
}
return res;

单行脚本:

boolean res = false; for(int i = 0; i < params['_source']['process'].length; i++){ if(params['_source']['process'][i]['processDefinitionKey'] == 'service_agreement' && !params['_source']['process'][i].containsKey('ended')) { res = true; break; }} return res;

脚本化字段将是boolean类型。

希望这可以帮助!

于 2018-12-20T09:11:26.323 回答