输入数据格式和结构

如需构建新索引或更新现有索引,请按照以下部分所述的格式和结构向 Vector Search 提供向量。

输入数据存储和文件组织

前提条件

将输入数据存储在 Google Cloud 项目的 Cloud Storage 存储桶中。

输入数据文件应按以下方式组织:

  • 每批输入数据文件应位于单个 Cloud Storage 目录下。
  • 数据文件应直接放在 batch_root 下,并采用以下后缀进行命名:.csv.json.avro
  • 批处理根目录中的对象(文件)数量上限为 5,000 个。
  • 每个数据文件都被解释为一组记录。记录的格式由文件名的后缀决定,相关文档介绍了这些格式要求。请参阅数据文件格式
  • 每个记录都应具有 id、特征向量以及 Vertex AI Feature Store 支持的可选字段,例如 restricts 和 crowding。
  • 可能存在名为 delete 的子目录。每个直接位于 batch_root/delete 下的文件都被视为包含 id 记录的文本文件,并且每个 id 占一行。
  • 其他所有目录和文件都会被忽略。

输入数据处理

  • 来自所有数据文件的所有记录(包括 delete 下的记录)都包含一批输入。
  • 数据文件中记录的相对排序无关紧要。
  • 一个 ID 在一个批次中只应出现一次。如果存在具有相同 ID 的重复记录,将显示为一个向量计数。
  • 一个 ID 不能同时出现在常规数据文件和删除数据文件中。
  • delete 目录下的数据文件中的所有 ID 都会使其从下一个索引版本中移除。
  • 常规数据文件中的记录包含在下一个版本中,并覆盖旧索引版本中的值。

以下是一个 JSON 示例:

{"id": "1", "embedding": [1,1,1]}
{"id": "2", "embedding": [2,2,2]}

下面是一个有效输入数据文件组织的示例:

batch_root/
  feature_file_1.csv
  feature_file_2.csv
  delete/
    delete_file.txt

feature_file_1.csvfeature_file_2.csv 文件包含 CSV 格式的记录。delete_file.txt 文件包含要从下一个索引版本中删除的记录 ID 列表。

数据文件格式

JSON

  • 使用 UTF-8 对 JSON 文件编码。
  • JSON 文件的每一行都会被解释为一个单独的 JSON 对象。
  • 每个记录都必须包含一个 id 字段,以指定向量的 ID。
  • 每个记录都必须包含一个 embedding 字段,该字段是表示特征向量的 N 浮点数字的数组,其中 N 是创建索引时配置的特征向量的维度。
  • 可以包含可选的 restricts 字段,用于指定 restricts 中的 TokenNamespace 对象数组。对于每个对象:
    • 指定 namespace 字段,即 TokenNamespace.namespace
    • 可选的 allow 字段可以设置为字符串数组,即 TokenNamespace.string_tokens 列表。
    • 可选的 deny 字段可以设置为字符串数组,即 TokenNamespace.string_blacklist_tokens 列表。
    • crowding_tag 字段(如果存在)的值必须是一个字符串。
  • 可以包含可选的 numeric_restricts 字段,用于指定 NumericRestrictNamespace 数组。对于每个对象:
    • 指定 namespace 字段,即 NumericRestrictNamespace.namespace
    • 值字段 value_intvalue_floatvalue_double 之一。
    • 该字段不得包含名为 op 的字段。此字段仅适用于查询。

Avro

  • 使用有效的 Avro 文件。
  • 创建符合以下架构的记录:

    {
      "type": "record",
      "name": "FeatureVector",
      "fields": [
        {
          "name": "id",
          "type": "string"
        },
        {
          "name": "embedding",
          "type": {
            "type": "array",
            "items": "float"
          }
        },
        {
          "name": "restricts",
          "type": [
            "null",
            {
              "type": "array",
              "items": {
                "type": "record",
                "name": "Restrict",
                "fields": [
                  {
                    "name": "namespace",
                    "type": "string"
                  },
                  {
                    "name": "allow",
                    "type": [
                      "null",
                      {
                        "type": "array",
                        "items": "string"
                      }
                    ]
                  },
                  {
                    "name": "deny",
                    "type": [
                      "null",
                      {
                        "type": "array",
                        "items": "string"
                      }
                    ]
                  }
                ]
              }
            }
          ]
        },
        {
          "name": "numeric_restricts",
          "type": [
            "null",
            {
              "type": "array",
              "items": {
                "name": "NumericRestrict",
                "type": "record",
                "fields": [
                  {
                    "name": "namespace",
                    "type": "string"
                  },
                  {
                    "name": "value_int",
                    "type": [ "null", "int" ],
                    "default": null
                  },
                  {
                    "name": "value_float",
                    "type": [ "null", "float" ],
                    "default": null
                  },
                  {
                    "name": "value_double",
                    "type": [ "null", "double" ],
                    "default": null
                  }
                ]
              }
            }
          ],
          "default": null
        },
        {
          "name": "crowding_tag",
          "type": [
            "null",
            "string"
          ]
        }
      ]
    }
    

CSV

  • 使用 UTF-8 对 CSV 文件编码。
  • CSV 中的每一行必须只包含一条记录。
  • 每行中的第一个值必须是向量 ID,它必须是有效的 UTF-8 字符串。
  • 在 ID 之后,接下来的 N 值表示特征向量,其中 N 是在创建索引时配置的特征向量的维度。
  • 特征向量值必须是 Java 语言规范中定义的浮点字面量。
  • 其他值可以采用 name=value 格式。
  • 名称 crowding_tag 会被解释为拥挤标记,并且只能在记录中出现一次。
  • 所有其他 name=value 对都会被解释为词元命名空间限制。如果命名空间中有多个值,则同一名称可以重复。

    例如,color=red,color=blue 表示此 TokenNamespace

    {
      "namespace": "color"
      "string_tokens": ["red", "blue"]
    }
    
  • 如果值以 ! 开头,则字符串的其余部分被解释为排除的值。

    例如,color=!red 表示此 TokenNamespace

    {
      "namespace": "color"
      "string_blacklist_tokens": ["red"]
    }
    
  • 带有数字类型后缀的 #name=numericValue 对会被解释为数字命名空间限制。数字类型后缀为 i(表示 int)、f(表示浮点)和 d(表示双精度)。同一名称不应重复,因为每个命名空间应该有一个关联的值。

    例如,#size=3i 表示此 NumericRestrictNamespace

    {
      "namespace": "size"
      "value_int": 3
    }
    

    #ratio=0.1f 表示此 NumericRestrictNamespace

    {
      "namespace": "ratio"
      "value_float": 0.1
    }
    

    #weight=0.3d 表示此 NumericRestriction

    {
      "namespace": "weight"
      "value_double": 0.3
    }
    

后续步骤