The Document class contains only final fields (except "embeddings" which is about to be removed). However, the media (collection) and metadata (map) are mutable. All vector store implementations, at least, rely on the metadata field to be mutable because they add new metadata.

https://github.com/spring-projects/spring-ai/pull/1794 introduced a mutate() method to build new instances of Document objects. This issue is to discuss whether Document should be immutable. If yes, we need to to refactor all vector store implementations to work accordingly. Also, it's a breaking change, so it should be documented and communicated in the release notes.

Comment From: markpollack

Also, there seems to be an inconsistency in what we want to be nullable in the current set of constructors vs. the builder, where only score is nullable. The builder should prob check that items are not nullable.

Comment From: markpollack

I looked at a few implementations of the VectorStores, but don't see that we are adding metadata to an existing instace of document, instead we are creating a new instance. It seems from first glance this would not be a big change, and even if it was, I think the immutability aspect is important to have.

Comment From: ThomasVitale

I agree on turning Document into a fully immutable object. The vector store implementations for Elasticsearch and OpenSearch parse the database result directly into a Document object and then subsequently add metadata to it (primarily, the "distance" metadata that we could probably remove entirely since now we have the "score" field). That should be easily fixable.

Comment From: markpollack

At the moment it looks to be mutable, there is the ability to set the contentFormatter though, but that doesn't change the data. Thoughts @ThomasVitale ?