丰富 Elastic Search 中的数据

Enriching the Data in Elastic Search

我们会将数据提取到索引 (Index1) 中,但是文档 (field1) 中的一个字段是一个 ENUM 值,需要使用通过 rest 的查找将其转换为一个值(字符串) api打电话。 其余 api 调用给出了一个 JSON 作为响应,其中包含所有 ENUMS 的字符串值。

{
values : {
"ENUMVALUE1" : "StringValue1",
"ENUMVALUE2" : "StringValue2"
}
}

我正在考虑根据此响应文档创建一个索引并将其用于查找。 传入文档的 field1 为 ENUMVALUE1 或 ENUMVALUE2(只有其中之一),我们希望最终将 StringValue1 或 StringValue2 保存在 field1 下的文档中,而不是 ENUMVALUE1。

我查看了浓缩处理器的文档,但是我不确定这是否是处理这种情况的正确方法。 在形成匹配丰富策略时,我不确定 match_field 和 enrich_fields 应该如何配置。

能否请您告知这是否可以在 Elastic 中完成?如果可以,如果上述方法不是最佳方法,我有哪些可能的选择。

好的,150-200 个枚举可能不足以使用丰富索引,但这是一个潜在的解决方案。

您首先需要 build the source index 包含所有枚举映射,它看起来像这样:

POST enums/_doc/_bulk
{"index":{}}
{"enum_id": "ENUMVALUE1", "string_value": "StringValue1"}
{"index":{}}
{"enum_id": "ENUMVALUE2", "string_value": "StringValue2"}

那你需要create an enrich policy出这个索引:

PUT /_enrich/policy/enum-policy
{
  "match": {
    "indices": "enums",
    "match_field": "enum_id",
    "enrich_fields": [
      "string_value"
    ]
  }
}
POST /_enrich/policy/enum-policy/_execute

构建完成后(使用 200 个值应该需要几秒钟),您可以使用 ingest processor:

开始构建您的摄取管道
PUT _ingest/pipeline/enum-pipeline
{
  "description": "Enum enriching pipeline",
  "processors": [
    {
      "enrich" : {
        "policy_name": "enum-policy",
        "field" : "field1",
        "target_field": "tmp"
      }
    },
    {
      "set": {
        "if": "ctx.tmp != null",
        "field": "field1",
        "value": "{{tmp.string_value}}"
      }
    },
    {
      "remove": {
        "if": "ctx.tmp != null",
        "field": "tmp"
      }
    }
  ]
}

测试这个管道,我们得到这个:

POST _ingest/pipeline/enum-pipeline/_simulate
{
  "docs": [
    {
      "_source": {
        "field1": "ENUMVALUE1"
      }
    },
    {
      "_source": {
        "field1": "ENUMVALUE4"
      }
    }
  ]
}

结果=>

{
  "docs" : [
    {
      "doc" : {
        "_source" : {
          "field1" : "StringValue1"        <--- value has been replaced
        }
      }
    },
    {
      "doc" : {
        "_source" : {
          "field1" : "ENUMVALUE4"          <--- value has NOT been replaced
        }
      }
    }
  ]
}

为了完整起见,我分享了另一个没有丰富索引的解决方案,因此您可以测试两者并使用对您最有意义的那个。

在第二个选项中,我们将简单地使用带有 script processor 的摄取管道,其参数包含您的枚举映射。 field1 将被映射到它包含的枚举值的任何值替换,或者如果没有对应的枚举值将保留它的值。

PUT _ingest/pipeline/enum-pipeline
{
  "description": "Enum enriching pipeline",
  "processors": [
    {
      "script": {
        "source": """
          ctx.field1 = params.getOrDefault(ctx.field1, ctx.field1);
        """,
        "params": {
          "ENUMVALUE1": "StringValue1",
          "ENUMVALUE2": "StringValue2",
          ... // add all your enums here
        }
      }
    }
  ]
}

测试这个管道,我们得到这个

POST _ingest/pipeline/enum-pipeline/_simulate
{
  "docs": [
    {
      "_source": {
        "field1": "ENUMVALUE1"
      }
    },
    {
      "_source": {
        "field1": "ENUMVALUE4"
      }
    }
  ]
}

结果=>

{
  "docs" : [
    {
      "doc" : {
        "_source" : {
          "field1" : "StringValue1"        <--- value has been replaced
        }
      }
    },
    {
      "doc" : {
        "_source" : {
          "field1" : "ENUMVALUE4"          <--- value has NOT been replaced
        }
      }
    }
  ]
}

所以这两种解决方案都适用于您的情况,您只需要选择最适合的那一种即可。只要知道在第一个选项中,如果您的枚举发生变化,您将需要重建源索引并丰富策略,而在第二种情况下,您只需要修改管道的参数映射。