Link Search Menu Expand Document Documentation Menu

处理字段类型中的破坏性变更

本指南解释了如何使用迁移助手在迁移到 OpenSearch 期间转换已弃用或不兼容的字段类型。

字段类型定义了数据在索引中如何存储和查询。文档中的每个字段都映射到一种数据类型,该数据类型决定了其索引方式以及可对其执行的操作。

例如,以下图书馆藏书的索引映射定义了三个字段,每个字段都具有不同的类型

GET /library-books/_mappings
{
  "library-books": {
    "mappings": {
      "properties": {
        "title":          { "type": "text" },
        "publishedDate":  { "type": "date" },
        "pageCount":      { "type": "integer" }
      }
    }
  }
}

有关更多信息,请参阅映射和字段类型

配置项转换

您可以通过执行以下步骤提供转换配置文件,以自定义元数据和数据迁移期间字段类型的转换方式

  1. 打开迁移助手控制台。
  2. 使用以下命令创建 JavaScript 文件以定义您的转换逻辑

    vim /shared-logs-output/field-type-converter.js
    

  3. 编写任何执行所需字段类型转换的 JavaScript 规则。有关如何实现规则的示例,请参阅示例 field-type-converter.js 实现
  4. 使用以下命令创建转换描述符文件

    vim /shared-logs-output/transformation.json
    

  5. transformation.json 中添加对您的 JavaScript 文件的引用。
  6. 运行元数据迁移,并使用类似以下命令提供转换配置

    console metadata migrate \
      --transformer-config-file /shared-logs-output/transformation.json
    

示例 field-type-converter.js 实现

以下脚本演示了如何执行常见的字段类型转换,包括

  • 将已弃用的 string 类型替换为 text
  • flattened 转换为 flat_object,并删除 index 属性(如果存在)。
function main(context) {
  const rules = [
    {
      when: { type: "string" },
      set: { type: "text" }
    },
    {
      when: { type: "flattened" },
      set: { type: "flat_object" },
      remove: ["index"]
    }
  ];

  function applyRules(node, rules) {
    if (Array.isArray(node)) {
      node.forEach((child) => applyRules(child, rules));
    } else if (node instanceof Map) {
      for (const { when, set, remove = [] } of rules) {
        const matches = Object.entries(when).every(([k, v]) => node.get(k) === v);
        if (matches) {
          Object.entries(set).every(([k, v]) => node.set(k, v));
          remove.forEach((key) => node.delete(key));
        }
      }
      for (const child of node.values()) {
        applyRules(child, rules);
      }
    } else if (node && typeof node === "object") {
      for (const { when, set, remove = [] } of rules) {
        const matches = Object.entries(when).every(([k, v]) => node[k] === v);
        if (matches) {
          Object.assign(node, set);
          remove.forEach((key) => delete node[key]);
        }
      }
      Object.values(node).forEach((child) => applyRules(child, rules));
    }
  }

  return (doc) => {
    if (doc && doc.type && doc.name && doc.body) {
      applyRules(doc, rules);
    }
    return doc;
  };
}
(() => main)();

该脚本包含以下元素

  1. rules 数组定义了转换逻辑

    • when:用于匹配节点上的键值条件
    • set:当 when 子句匹配时应用的键值对
    • remove(可选):匹配时要从节点中删除的键
  2. applyRules 函数递归遍历输入

    • 数组按元素递归处理。
    • Map 对象使用定义的规则进行匹配和修改。
    • 对普通对象进行匹配检查并相应地进行转换。
  3. main 函数返回一个转换函数,该函数

    • 将规则应用于每个文档。
    • 返回修改后的文档以进行迁移或重放。

示例 transformation.json

以下 JSON 文件引用您的转换脚本,并使用您的自定义规则初始化 JavaScript 引擎

[
  {
    "JsonJSTransformerProvider": {
      "initializationScriptFile": "/shared-logs-output/field-type-converter.js",
      "bindingsObject": "{}"
    }
  }
]

总结

通过使用转换配置,您可以在元数据迁移或数据重放期间重写已弃用或不兼容的字段类型。这确保了您的目标 OpenSearch 集群只接收兼容的映射——即使源集群包含像 string 这样的过时类型或像 flattened 这样需要转换的功能。

剩余 350 字符

有问题?

想贡献?