Skip to content

Support metadata-only update operations in PGVectorStore (design discussion) #281

Description

Support metadata-only update operations in PGVectorStore (design discussion)

Summary

I’d like to start a discussion about whether PGVectorStore should support metadata-only update operations without re-embedding.

Currently, updating metadata requires deleting and re-adding documents, which recomputes embeddings even when the content itself has not changed.

Before working on a PR, I would like to better understand whether this fits within the intended abstraction of PGVectorStore.


Motivation

There are several practical cases where only metadata changes:

  • Title or label updates
  • Status transitions (draft → published, active → archived)
  • Metadata enrichment after indexing
  • Corrections of metadata errors

At the moment, the typical workaround is:

  1. Query documents
  2. Delete them
  3. Re-add them with updated metadata

This approach:

  • Recomputes embeddings unnecessarily
  • Can be costly when using paid embedding APIs
  • Encourages users to bypass the abstraction and run raw SQL directly

For example:

cursor.execute(
    """
    UPDATE "my_table"
    SET langchain_metadata = jsonb_set(
        COALESCE(langchain_metadata::jsonb, '{}'::jsonb),
        '{video_title}',
        to_jsonb(%s::text)
    )
    WHERE video_id = %s
    """,
    [new_title, video_id],
)

This breaks the abstraction boundary and tightly couples applications to the internal schema.


Proposal (for discussion)

One possible API could be:

vectorstore.update(
    filter={"video_id": 123},
    metadata={"video_title": "New Title"},
)

Or:

vectorstore.update(
    ids=["doc-id-1"],
    metadata={"status": "archived"},
)

The method would:

  • Only modify metadata
  • Not touch embeddings
  • Return the number of updated rows

Design Questions

I would appreciate feedback on the following:

  1. Does supporting metadata-only updates align with the intended design philosophy of PGVectorStore?
  2. Should update semantics be strictly limited to metadata?
  3. Is there an architectural reason this capability was intentionally omitted?

If this direction is considered appropriate, I would be happy to explore a PR.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions