Redis(
self,
redis_url: str,
index_name: str,
embedding: Embeddings,
Redis vector database.
Deployment Options:
Below, we will use a local deployment as an example. However, Redis can be deployed in all of the following ways:
Setup:
Install redis, redisvl, and langchain-community and run Redis locally.
.. code-block:: bash
pip install -qU redis redisvl langchain-community
docker run -d -p 6379:6379 -p 8001:8001 redis/redis-stack:latest
Key init args — indexing params: index_name: str Name of the index. index_schema: Optional[Union[Dict[str, ListOfDict], str, os.PathLike]] Schema of the index and the vector schema. Can be a dict, or path to yaml file. embedding: Embeddings Embedding function to use.
Key init args — client params: redis_url: str Redis connection url.
Instantiate:
.. code-block:: python
from langchain_community.vectorstores.redis import Redis from langchain_openai import OpenAIEmbeddings
vector_store = Redis( redis_url="redis://localhost:6379", embedding=OpenAIEmbeddings(), index_name="users", )
Add Documents:
.. code-block:: python
from langchain_core.documents import Document
document_1 = Document(page_content="foo", metadata={"baz": "bar"}) document_2 = Document(page_content="thud", metadata={"bar": "baz"}) document_3 = Document(page_content="i will be deleted :(")
documents = [document_1, document_2, document_3] ids = ["1", "2", "3"] vector_store.add_documents(documents=documents, ids=ids)
Delete Documents:
.. code-block:: python
vector_store.delete(ids=["3"])
Search:
.. code-block:: python
results = vector_store.similarity_search(query="thud",k=1)
for doc in results:
print(f"* {doc.page_content} [{doc.metadata}]")
.. code-block:: python
* thud [{'id': 'doc:users:2'}]
Search with filter:
.. code-block:: python
from langchain_community.vectorstores.redis import RedisTag
results = vector_store.similarity_search(query="thud",k=1,filter=(RedisTag("baz") != "bar"))
for doc in results:
print(f"* {doc.page_content} [{doc.metadata}]")
.. code-block:: python
* thud [{'id': 'doc:users:2'}]
Search with score:
.. code-block:: python
results = vector_store.similarity_search_with_score(query="qux",k=1)
for doc, score in results:
print(f"* [SIM={score:3f}] {doc.page_content} [{doc.metadata}]")
.. code-block:: python
* [SIM=0.167700] foo [{'id': 'doc:users:1'}]
Async:
.. code-block:: python
# add documents
# await vector_store.aadd_documents(documents=documents, ids=ids)
# delete documents
# await vector_store.adelete(ids=["3"])
# search
# results = vector_store.asimilarity_search(query="thud",k=1)
# search with score
results = await vector_store.asimilarity_search_with_score(query="qux",k=1)
for doc,score in results:
print(f"* [SIM={score:3f}] {doc.page_content} [{doc.metadata}]")
.. code-block:: python
* [SIM=0.167700] foo [{'id': 'doc:users:1'}]
Use as Retriever:
.. code-block:: python
retriever = vector_store.as_retriever(
search_type="mmr",
search_kwargs={"k": 1, "fetch_k": 2, "lambda_mult": 0.5},
)
retriever.invoke("thud")
.. code-block:: python
[Document(metadata={'id': 'doc:users:2'}, page_content='thud')]
Advanced examples:
Custom vector schema can be supplied to change the way that Redis creates the underlying vector schema. This is useful for production use cases where you want to optimize the vector schema for your use case. ex. using HNSW instead of FLAT (knn) which is the default
.. code-block:: python
vector_schema = {
"algorithm": "HNSW"
}
rds = Redis.from_texts(
texts, # a list of strings
metadata, # a list of metadata dicts
embeddings, # an Embeddings object
vector_schema=vector_schema,
redis_url="redis://localhost:6379",
)
Custom index schema can be supplied to change the way that the metadata is indexed. This is useful for you would like to use the hybrid querying (filtering) capability of Redis.
By default, this implementation will automatically generate the index schema according to the following rules: - All strings are indexed as text fields - All numbers are indexed as numeric fields - All lists of strings are indexed as tag fields (joined by langchain_community.vectorstores.redis.constants.REDIS_TAG_SEPARATOR) - All None values are not indexed but still stored in Redis these are not retrievable through the interface here, but the raw Redis client can be used to retrieve them. - All other types are not indexed
To override these rules, you can pass in a custom index schema like the following
.. code-block:: yaml
tag:
- name: credit_score
text:
- name: user
- name: job
Typically, the credit_score field would be a text field since it's a string,
however, we can override this behavior by specifying the field type as shown with
the yaml config (can also be a dictionary) above and the code below.
.. code-block:: python
rds = Redis.from_texts(
texts, # a list of strings
metadata, # a list of metadata dicts
embeddings, # an Embeddings object
index_schema="path/to/index_schema.yaml", # can also be a dictionary
redis_url="redis://localhost:6379",
)
When connecting to an existing index where a custom schema has been applied, it's
important to pass in the same schema to the from_existing_index method.
Otherwise, the schema for newly added samples will be incorrect and metadata
will not be returned.