Performing basic operations with Amazon S3 Vectors in Python and Node.js

Performing basic operations with Amazon S3 Vectors in Python and Node.js

Using Amazon S3 Vectors with Python and Node.js to verify the basic procedures of PutVectors / GetVectors / ListVectors / QueryVectors. We will validate vector search behavior while showing console preparations and SDK execution results.
2026.01.11

This page has been translated by machine translation. View original

Introduction

When creating AI chat or FAQ bots, there are often situations where you want the LLM to reference internal documents or product specifications. A representative method is RAG. RAG first searches for documents related to a question, then provides those documents to the LLM as context for answering. This makes it easier for the LLM to handle company-specific information or the latest information that would be difficult to answer with the LLM alone.

For RAG searches, it's common to convert documents into numerical vectors called embeddings and use vector search to find semantically similar documents.

embedding

To start vector searching, you need a system to store vectors and an index for searching. Setting up a dedicated vector DB requires cluster preparation, capacity estimation, scale design, monitoring, and more.

Amazon S3 Vectors allows you to store vectors in S3 and perform vector searches with dedicated APIs. On the application side, you create vector buckets and vector indexes, add vectors, and search. This allows you to start testing vector searches without setting up infrastructure for a separate service.

In this article, we'll explore how to work with Amazon S3 Vectors using Python and Node.js. We'll divide the scripts by function and execute them in sequence. Note that this article doesn't cover embedding itself. For operational verification, we'll use fixed vector values.

Target Audience

  • Those who can run the SDK using AWS authentication credentials
  • Those who want to test with Python, Node.js, or both
  • Those who want to understand Amazon S3 Vectors APIs

Test Environment

  • AWS CLI: 2.31.31
  • Python: 3.12.3
  • Node.js: 22.16.0
  • Region: ap-northeast-1

References

S3 Vectors Specifications

Amazon S3 Vectors creates vector indexes within vector buckets, and executes PutVectors / GetVectors / ListVectors / QueryVectors against those indexes.

Stored as float32, retrieved as float32

The data of vectors is handled as float32. Even if you pass a higher precision numeric type from the SDK, it will be converted to float32 on the S3 Vectors side, and GetVectors and QueryVectors will return float32 values.

Metadata has filterable and non-filterable types

Metadata filtering allows you to filter search results based on metadata values after searching by vector similarity. For example, you can target only vectors with a year of 2021 or higher. By default, metadata is filterable. Only keys specified during index creation can be made non-filterable.

Non-filterable metadata can be stored as additional information with vectors. It can be retrieved with returnMetadata in GetVectors and QueryVectors. However, it cannot be used as a filter condition in QueryVectors.

AWS Management Console Preparation

Here, we'll create a vector bucket and vector indexes in the console.

Creating a Vector Bucket

Open the Amazon S3 console and create a vector bucket from the S3 Vectors screen.

create vector bucket

Creating a Vector Index

Create vector indexes within the created vector bucket.

create vector index

In this article, we'll create two indexes:

  • movies (cosine)
  • movies-euclidean (euclidean)

We decide on dimensions and distance metrics. For this test, we'll use 1024 dimensions.

Also, we'll specify raw_text as non-filterable metadata.

vector index configs

After creation, confirm that the indexes appear in the index list.

index list

Environment Variables

In the following examples, we'll use these environment variables:

Variable Name Value
VECTOR_BUCKET_NAME test-s3-vector-bucket
INDEX_NAME movies
INDEX_NAME_EUC movies-euclidean
DIMENSION 1024
AWS_REGION ap-northeast-1

Operating with Python

Installing Dependencies

Create a virtual environment and install boto3.

python3 -m venv .venv
source .venv/bin/activate
pip install boto3

env_check.py

This script is used to detect missing environment variables early.

import os
import sys

REQUIRED = ["AWS_REGION", "VECTOR_BUCKET_NAME", "INDEX_NAME", "INDEX_NAME_EUC", "DIMENSION"]

missing = [k for k in REQUIRED if not os.getenv(k)]
if missing:
    print("Missing env:", ", ".join(missing))
    sys.exit(1)

print("OK")

Execution result

OK

put_vectors.py

Add a vector. Here we insert one record, doc1.

import os
import boto3

region = os.environ["AWS_REGION"]
bucket = os.environ["VECTOR_BUCKET_NAME"]
index_name = os.environ["INDEX_NAME"]
dim = int(os.environ["DIMENSION"])

def vec(first: float) -> list[float]:
    v = [0.0] * dim
    v[0] = first
    return v

client = boto3.client("s3vectors", region_name=region)

client.put_vectors(
    vectorBucketName=bucket,
    indexName=index_name,
    vectors=[
        {
            "key": "doc1",
            "data": {"float32": vec(0.1)},
            "metadata": {"genre": "mystery", "year": 2020, "raw_text": "hello"},
        }
    ],
)

print("put-vectors: done")

Execution result

put-vectors: done

get_vectors.py

Retrieve the added vector. If returnData and returnMetadata are not set to True, only the key is returned. When DIMENSION is 1024, data.float32 has 1024 elements, so for this test, we'll only display the first few elements.

import os
import boto3

region = os.environ["AWS_REGION"]
bucket = os.environ["VECTOR_BUCKET_NAME"]
index_name = os.environ["INDEX_NAME"]
dim = int(os.environ["DIMENSION"])

client = boto3.client("s3vectors", region_name=region)

res = client.get_vectors(
    vectorBucketName=bucket,
    indexName=index_name,
    keys=["doc1"],
    returnData=True,
    returnMetadata=True,
)

v = res["vectors"][0]
data = v.get("data", {}).get("float32", [])

print(f"key: {v['key']}")
print(f"dimension: {len(data)} / expected: {dim}")
print(f"data[0:8]: {data[:8]}")
print(f"metadata: {v.get('metadata')}")

Execution result

key: doc1
dimension: 1024 / expected: 1024
data[0:8]: [0.10000000149011612, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
metadata: {'raw_text': 'hello', 'genre': 'mystery', 'year': 2020}

list_vectors.py

Get a list of vectors in the index. Here we set returnMetadata to True to check the associated information.

import os
import boto3
import json

region = os.environ["AWS_REGION"]
bucket = os.environ["VECTOR_BUCKET_NAME"]
index_name = os.environ["INDEX_NAME"]

client = boto3.client("s3vectors", region_name=region)

res = client.list_vectors(
    vectorBucketName=bucket,
    indexName=index_name,
    returnMetadata=True,
)

print(json.dumps(res, ensure_ascii=False, indent=2))

Execution result

{
  "ResponseMetadata": {
    (abbreviated)
  },
  "vectors": [
    {
      "key": "doc1",
      "metadata": {
        "year": 2020,
        "genre": "mystery",
        "raw_text": "hello"
      }
    }
  ]
}

query_vectors.py

Perform similarity search without filtering. You need to provide a query vector with the same length as DIMENSION.

import os
import boto3
import json

region = os.environ["AWS_REGION"]
bucket = os.environ["VECTOR_BUCKET_NAME"]
index_name = os.environ["INDEX_NAME"]
dim = int(os.environ["DIMENSION"])

def vec(first: float) -> list[float]:
    v = [0.0] * dim
    v[0] = first
    return v

client = boto3.client("s3vectors", region_name=region)

res = client.query_vectors(
    vectorBucketName=bucket,
    indexName=index_name,
    topK=5,
    queryVector={"float32": vec(0.19)},
    returnDistance=True,
    returnMetadata=True,
)

print(json.dumps(res, ensure_ascii=False, indent=2))

Here, vec(0.19) is a DIMENSION-dimensional vector created by the helper function vec(first). Specifically, only the first element is 0.19, and the rest are all 0.0. Similarly, vec(0.1) has only the first element as 0.1, with the rest all being 0.0. These two are related by scalar multiplication and can be treated as vectors with the same direction.

Cosine similarity is defined by the following formula:

\cos(\mathbf{a}, \mathbf{b}) = \frac{\mathbf{a} \cdot \mathbf{b}}{\lVert \mathbf{a} \rVert \, \lVert \mathbf{b} \rVert}

If \mathbf{a} and \mathbf{b} point in the same direction, \cos(\mathbf{a}, \mathbf{b}) = 1. When S3 Vectors' distanceMetric is cosine, distance is calculated such that higher similarity results in smaller distance, so the distance between vectors in the same direction is 0.0.

Execution result

{
  "ResponseMetadata": {
    (abbreviated)
  },
  "vectors": [
    {
      "distance": 0.0,
      "key": "doc1",
      "metadata": {
        "genre": "mystery",
        "raw_text": "hello",
        "year": 2020
      }
    }
  ],
  "distanceMetric": "cosine"
}

From the execution result, we can see that the distance is indeed calculated as 0.0.

query_vectors_filter.py

Use metadata filter to narrow down results. Here we target only those with year 2021 or higher. The filter syntax has examples on the metadata filtering page.

First, let's update doc1. PutVectors can be reinvested against the same key, so it can be treated as an update.

import os
import boto3

region = os.environ["AWS_REGION"]
bucket = os.environ["VECTOR_BUCKET_NAME"]
index_name = os.environ["INDEX_NAME"]
dim = int(os.environ["DIMENSION"])

def vec(first: float) -> list[float]:
    v = [0.0] * dim
    v[0] = first
    return v

client = boto3.client("s3vectors", region_name=region)

client.put_vectors(
    vectorBucketName=bucket,
    indexName=index_name,
    vectors=[
        {
            "key": "doc1",
            "data": {"float32": vec(0.2)},
            "metadata": {"genre": "mystery", "year": 2021, "raw_text": "hello2"},
        }
    ],
)

print("put-vectors: updated")

Next, query with a filter.

import os
import boto3
import json

region = os.environ["AWS_REGION"]
bucket = os.environ["VECTOR_BUCKET_NAME"]
index_name = os.environ["INDEX_NAME"]
dim = int(os.environ["DIMENSION"])

def vec(first: float) -> list[float]:
    v = [0.0] * dim
    v[0] = first
    return v

client = boto3.client("s3vectors", region_name=region)

res = client.query_vectors(
    vectorBucketName=bucket,
    indexName=index_name,
    topK=5,
    queryVector={"float32": vec(0.19)},
    returnDistance=True,
    returnMetadata=True,
    filter={"$and": [{"genre": {"$eq": "mystery"}}, {"year": {"$gte": 2021}}]},
)

print(json.dumps(res, ensure_ascii=False, indent=2))

Execution result

put-vectors: updated
{
  "ResponseMetadata": {
    (abbreviated)
  },
  "vectors": [
    {
      "distance": 0.0,
      "key": "doc1",
      "metadata": {
        "raw_text": "hello2",
        "year": 2021,
        "genre": "mystery"
      }
    }
  ],
  "distanceMetric": "cosine"
}

query_vectors_non_filterable.py

Including non-filterable metadata in a filter will fail. Since we made raw_text non-filterable, the following query will result in a ValidationException.

import os
import boto3

region = os.environ["AWS_REGION"]
bucket = os.environ["VECTOR_BUCKET_NAME"]
index_name = os.environ["INDEX_NAME"]
dim = int(os.environ["DIMENSION"])

def vec(first: float) -> list[float]:
    v = [0.0] * dim
    v[0] = first
    return v

client = boto3.client("s3vectors", region_name=region)

client.query_vectors(
    vectorBucketName=bucket,
    indexName=index_name,
    topK=5,
    queryVector={"float32": vec(0.19)},
    filter={"raw_text": {"$eq": "hello"}},
)

Execution result

Traceback (most recent call last):
  File "query_vectors_non_filterable.py", line 15, in <module>
    client.query_vectors(
  File ".venv/lib/python3.12/site-packages/botocore/client.py", line 602, in _api_call
    return self._make_api_call(operation_name, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/botocore/context.py", line 123, in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/botocore/client.py", line 1078, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.errorfactory.ValidationException: An error occurred (ValidationException) when calling the QueryVectors operation: Invalid use of non-filterable metadata in filter

delete_vectors.py

Delete vectors.

import os
import boto3

region = os.environ["AWS_REGION"]
bucket = os.environ["VECTOR_BUCKET_NAME"]
index_name = os.environ["INDEX_NAME"]

client = boto3.client("s3vectors", region_name=region)

client.delete_vectors(
    vectorBucketName=bucket,
    indexName=index_name,
    keys=["doc1"],
)

print("delete-vectors: done")

Execution result

delete-vectors: done

Run list_vectors.py after deletion to confirm it's empty.

Execution result

{
  "ResponseMetadata": {
    (abbreviated)
  },
  "vectors": []
}

check_euclidean.py

Insert vec(0.1) into movies-euclidean, search with vec(0.19), and check the distance.

Euclidean is a distance metric that uses straight-line distance. Euclidean distance is generally defined by the following formula:

d(\mathbf{a}, \mathbf{b}) = \sqrt{\sum_{i=1}^{n} (a_i - b_i)^2}

However, the distance returned by S3 Vectors in the QueryVectors response is described as a computed distance or measure of similarity, and may not match the mathematical Euclidean distance. Therefore, this script calculates both Euclidean distance (L2) and squared distance (L2 squared) to see which one the returned distance is closer to.

Note that since our vec(first) has only the first element as non-zero, even with a DIMENSION of 1024, there's only one element with a difference. Therefore, the theoretical L2 is |0.19 - 0.1|.

import os
import time
import boto3

region = os.environ["AWS_REGION"]
bucket = os.environ["VECTOR_BUCKET_NAME"]
index_name = os.environ["INDEX_NAME_EUC"]
dim = int(os.environ["DIMENSION"])

KEY = "doc-euc-1"

def vec(first: float) -> list[float]:
    v = [0.0] * dim
    v[0] = first
    return v

client = boto3.client("s3vectors", region_name=region)

inserted = False

try:
    client.put_vectors(
        vectorBucketName=bucket,
        indexName=index_name,
        vectors=[
            {
                "key": KEY,
                "data": {"float32": vec(0.1)},
                "metadata": {"note": "euclidean quick check"},
            }
        ],
    )
    inserted = True

    # 1. Wait for reflection: Check existence with GetVectors (max 10 times)
    for _ in range(10):
        g = client.get_vectors(
            vectorBucketName=bucket,
            indexName=index_name,
            keys=[KEY],
        )
        if g.get("vectors"):
            break
        time.sleep(0.3)

    # 2. Wait for reflection: Search with QueryVectors (max 10 times)
    res = None
    for _ in range(10):
        res = client.query_vectors(
            vectorBucketName=bucket,
            indexName=index_name,
            topK=1,
            queryVector={"float32": vec(0.19)},
            returnDistance=True,
        )
        if res.get("vectors"):
            break
        time.sleep(0.3)

    if not res or not res.get("vectors"):
        # Even if empty, don't drop but output the situation
        print("distanceMetric:", (res or {}).get("distanceMetric"))
        print("vectors: []")
        print("note: QueryVectors returned no results. Try again, or check indexName and data presence.")
        raise SystemExit(1)

    returned = res["vectors"][0]["distance"]

    delta = 0.19 - 0.1
    expected_l2 = abs(delta)
    expected_l2_squared = delta * delta

    print("distanceMetric:", res.get("distanceMetric"))
    print("distance:", returned)
    print("expected_l2:", expected_l2)
    print("expected_l2_squared:", expected_l2_squared)

finally:
    if inserted:
        client.delete_vectors(
            vectorBucketName=bucket,
            indexName=index_name,
            keys=[KEY],
        )

Execution result (example)

distanceMetric: euclidean
distance: 0.007821191102266312
expected_l2: 0.09
expected_l2_squared: 0.0081

In actual measurement, the distance returned by S3 Vectors was closer to L2 squared than L2. It's safer to treat S3 Vectors' distance as an indicator for ranking rather than assuming it perfectly matches mathematical distance. If you need to compare values, it's better to make relative comparisons between data with the same distanceMetric and scale.

Operating with Node.js

Installing Dependencies

Use the AWS SDK for JavaScript's S3 Vectors client.

npm init -y
npm install @aws-sdk/client-s3vectors

env_check.js

Similar to Python, we detect missing environment variables early. In the Node.js section, we'll use only the cosine index and omit euclidean.

const required = ["AWS_REGION", "VECTOR_BUCKET_NAME", "INDEX_NAME", "DIMENSION"];
const missing = required.filter((k) => !process.env[k]);

if (missing.length) {
  console.error(`Missing env: ${missing.join(", ")}`);
  process.exit(1);
}

console.log("OK");

Execution result

OK

put_vectors.js

Add a vector. Here we insert one record, doc1.

const { S3VectorsClient, PutVectorsCommand } = require("@aws-sdk/client-s3vectors");

const region = process.env.AWS_REGION;
const vectorBucketName = process.env.VECTOR_BUCKET_NAME;
const indexName = process.env.INDEX_NAME;
const dim = Number(process.env.DIMENSION);

const vec = (first) => {
  const v = Array(dim).fill(0);
  v[0] = first;
  return v;
};

(async () => {
  const client = new S3VectorsClient({ region });

  await client.send(
    new PutVectorsCommand({
      vectorBucketName,
      indexName,
      vectors: [
        {
          key: "doc1",
          data: { float32: vec(0.1) },
          metadata: { genre: "mystery", year: 2020, raw_text: "hello" },
        },
      ],
    })
  );

  console.log("put-vectors: done");
})().catch((e) => {
  console.error(e?.name, e?.message);
  process.exit(1);
});

Execution result

put-vectors: done

get_vectors.js

Retrieve the added vector. If returnData and returnMetadata are not set to true, only the key is returned. For large DIMENSION values, we display only the first few elements.

const { S3VectorsClient, GetVectorsCommand } = require("@aws-sdk/client-s3vectors");

const region = process.env.AWS_REGION;
const vectorBucketName = process.env.VECTOR_BUCKET_NAME;
const indexName = process.env.INDEX_NAME;
const dim = Number(process.env.DIMENSION);

(async () => {
  const client = new S3VectorsClient({ region });

  const res = await client.send(
    new GetVectorsCommand({
      vectorBucketName,
      indexName,
      keys: ["doc1"],
      returnData: true,
      returnMetadata: true,
    })
  );

  const v = res.vectors?.[0];
  const data = v?.data?.float32 ?? [];

  console.log(`key: ${v?.key}`);
  console.log(`dimension: ${data.length} / expected: ${dim}`);
  console.log(`data[0:8]: ${JSON.stringify(data.slice(0, 8))}`);
  console.log(`metadata: ${JSON.stringify(v?.metadata)}`);
})().catch((e) => {
  console.error(e?.name, e?.message);
  process.exit(1);
});

Execution result

key: doc1
dimension: 1024 / expected: 1024
data[0:8]: [0.10000000149011612,0,0,0,0,0,0,0]
metadata: {"year":2020,"raw_text":"hello","genre":"mystery"}

list_vectors.js

Get a list of vectors in the index. Here we set returnMetadata to true to check the associated information.

const { S3VectorsClient, ListVectorsCommand } = require("@aws-sdk/client-s3vectors");

const region = process.env.AWS_REGION;
const vectorBucketName = process.env.VECTOR_BUCKET_NAME;
const indexName = process.env.INDEX_NAME;

(async () => {
  const client = new S3VectorsClient({ region });

  const res = await client.send(
    new ListVectorsCommand({
      vectorBucketName,
      indexName,
      returnMetadata: true,
    })
  );

  console.log(JSON.stringify(res, null, 2));
})().catch((e) => {
  console.error(e?.name, e?.message);
  process.exit(1);
});

Execution result

{
  "vectors": [
    {
      "key": "doc1",
      "metadata": {
        "raw_text": "hello",
        "genre": "mystery",
        "year": 2020
      }
    }
  ],
  "$metadata": {
    (abbreviated)
  }
}

query_vectors.js

Perform similarity search without filtering. You need to provide a query vector with the same length as DIMENSION.

const { S3VectorsClient, QueryVectorsCommand } = require("@aws-sdk/client-s3vectors");

const region = process.env.AWS_REGION;
const vectorBucketName = process.env.VECTOR_BUCKET_NAME;
const indexName = process.env.INDEX_NAME;
const dim = Number(process.env.DIMENSION);

const vec = (first) => {
  const v = Array(dim).fill(0);
  v[0] = first;
  return v;
};

(async () => {
  const client = new S3VectorsClient({ region });

  const res = await client.send(
    new QueryVectorsCommand({
      vectorBucketName,
      indexName,
      topK: 5,
      queryVector: { float32: vec(0.19) },
      returnDistance: true,
      returnMetadata: true,
    })
  );

  console.log(JSON.stringify(res, null, 2));
})().catch((e) => {
  console.error(e?.name, e?.message);
  process.exit(1);
});

Execution result

{
  "vectors": [
    {
      "distance": 0,
      "key": "doc1",
      "metadata": {
        "year": 2020,
        "genre": "mystery",
        "raw_text": "hello"
      }
    }
  ],
  "distanceMetric": "cosine",
  "$metadata": {
    (abbreviated)
  }
}

query_vectors_non_filterable.js

If raw_text is set as non-filterable metadata, including it in a filter will fail.

const { S3VectorsClient, QueryVectorsCommand } = require("@aws-sdk/client-s3vectors");

const region = process.env.AWS_REGION;
const vectorBucketName = process.env.VECTOR_BUCKET_NAME;
const indexName = process.env.INDEX_NAME;
const dim = Number(process.env.DIMENSION);

const vec = (first) => {
  const v = Array(dim).fill(0);
  v[0] = first;
  return v;
};

(async () => {
  const client = new S3VectorsClient({ region });

  try {
    await client.send(
      new QueryVectorsCommand({
        vectorBucketName,
        indexName,
        topK: 5,
        queryVector: { float32: vec(0.19) },
        filter: { raw_text: { $eq: "hello" } },
      })
    );
  } catch (e) {
    console.error("expected error:", e?.name, e?.message);
  }
})().catch((e) => {
  console.error(e?.name, e?.message);
  process.exit(1);
});

Execution result

expected error: ValidationException Invalid use of non-filterable metadata in filter

delete_vectors.js

As cleanup, we delete the added vectors.

const { S3VectorsClient, DeleteVectorsCommand } = require("@aws-sdk/client-s3vectors");

const region = process.env.AWS_REGION;
const vectorBucketName = process.env.VECTOR_BUCKET_NAME;
const indexName = process.env.INDEX_NAME;

(async () => {
  const client = new S3VectorsClient({ region });

  await client.send(
    new DeleteVectorsCommand({
      vectorBucketName,
      indexName,
      keys: ["doc1"],
    })
  );

  console.log("delete-vectors: done");
})().catch((e) => {
  console.error(e?.name, e?.message);
  process.exit(1);
});

Execution result

delete-vectors: done

Considerations

Division of Roles Between Console and SDK

Currently, the console can handle the creation of vector buckets and vector indexes. However, vector insertion, listing, and querying require the use of the AWS SDK / AWS CLI / REST API. While console functionality may be expanded in the future, it's valuable to establish SDK-based procedures first when considering operations. For example, vector insertion and updates work well with batch processing and CI, and procedures can be preserved along with logs. This can minimize the differences between verification and production migration compared to UI-only procedures.

Handling distanceMetric and distance

distanceMetric is the method for calculating similarity. Cosine evaluates similarity based on angles, while Euclidean evaluates similarity based on straight-line distance.

In this article's verification, the distance was 0.0 in the cosine example. In the Euclidean example, the value did not match the expected mathematical Euclidean distance (L2). Therefore, in implementation, it's safer not to rely too heavily on the absolute value of distance.

For example, L2 and L2 squared have a monotonically increasing relationship, so as long as you're ranking the same data, the top results won't fundamentally change. What's important is to relatively compare results with the same distanceMetric to extract the top ones.

However, caution is needed when setting thresholds on distances for pass/fail determinations. In such cases, it's safer to determine threshold values after observing distributions in actual data.

Scenarios for Choosing S3 Vectors

I found that S3 Vectors is a good choice in the following scenarios:

  • When you're already using S3 as a data lake and don't want to increase operational targets with a separate service just for vector search
  • When you want to start with small verifications without spending time on infrastructure design or cluster operations
  • When you want to use vector search as a component and freely design pre-processing and post-processing on the application side

However, if you just want to set up RAG with minimal steps, mechanisms like Amazon Bedrock Knowledge Bases that handle ingestion, segmentation, embedding, and search together are more suitable. Since S3 Vectors can also be used as a vector store for Knowledge Bases, you can first try with Knowledge Bases and later adjust based on requirements.

If you prioritize advanced search features or hybrid search, it may be more appropriate to design based on services with strong search capabilities, such as Amazon OpenSearch Service or DocumentDB. While DynamoDB is oriented toward transaction-based data placement, when focusing on vector search, many configuration examples combine it with OpenSearch, requiring selection based on requirements.

Summary

This article introduced how to create vector buckets and vector indexes with Amazon S3 Vectors, and how to manipulate vector data using PutVectors / GetVectors / ListVectors / QueryVectors. While the current console allows for resource creation and index listing, vector insertion and searching must be done through the AWS SDK / AWS CLI. In this article, we executed vector insertion and searching using both Python and Node.js, and confirmed actual behavior from the execution results. I hope this serves as a reference for verification and implementation of RAG.

Share this article

FacebookHatena blogX

Related articles