Skip to content

Commit

Permalink
qdrant[patch]: Use collection_exists API instead of exceptions (#22764)
Browse files Browse the repository at this point in the history
## Description

Currently, the Qdrant integration relies on exceptions raised by
[`get_collection`
](https://qdrant.tech/documentation/concepts/collections/#collection-info)
to check if a collection exists.

Using
[`collection_exists`](https://qdrant.tech/documentation/concepts/collections/#check-collection-existence)
is recommended to avoid missing any unhandled exceptions. This PR
addresses this.

## Testing
All integration and unit tests pass. No user-facing changes.
  • Loading branch information
Anush008 authored and hinthornw committed Jun 20, 2024
1 parent 5a1b63c commit f7bc198
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 27 deletions.
35 changes: 18 additions & 17 deletions libs/partners/qdrant/langchain_qdrant/vectorstores.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,12 @@
)

import numpy as np
from grpc import RpcError # type: ignore
from langchain_core.documents import Document
from langchain_core.embeddings import Embeddings
from langchain_core.runnables.config import run_in_executor
from langchain_core.vectorstores import VectorStore
from qdrant_client import AsyncQdrantClient, QdrantClient
from qdrant_client.http import models
from qdrant_client.http.exceptions import UnexpectedResponse
from qdrant_client.local.async_qdrant_local import AsyncQdrantLocal

from langchain_qdrant._utils import maximal_marginal_relevance
Expand Down Expand Up @@ -1636,14 +1634,16 @@ def construct_instance(
path=path,
**kwargs,
)
try:
# Skip any validation in case of forced collection recreate.
if force_recreate:
raise ValueError
collection_exists = client.collection_exists(collection_name)

if collection_exists and force_recreate:
client.delete_collection(collection_name)
collection_exists = False

if collection_exists:
# Get the vector configuration of the existing collection and vector, if it
# was specified. If the old configuration does not match the current one,
# an exception is being thrown.
# an exception is raised.
collection_info = client.get_collection(collection_name=collection_name)
current_vector_config = collection_info.config.params.vectors
if isinstance(current_vector_config, dict) and vector_name is not None:
Expand Down Expand Up @@ -1700,7 +1700,7 @@ def construct_instance(
f"If you want to recreate the collection, set `force_recreate` "
f"parameter to `True`."
)
except (UnexpectedResponse, RpcError, ValueError):
else:
vectors_config = models.VectorParams(
size=vector_size,
distance=models.Distance[distance_func],
Expand All @@ -1714,8 +1714,6 @@ def construct_instance(
vector_name: vectors_config,
}

if client.collection_exists(collection_name):
client.delete_collection(collection_name)
client.create_collection(
collection_name=collection_name,
vectors_config=vectors_config,
Expand Down Expand Up @@ -1795,14 +1793,17 @@ async def aconstruct_instance(
path=path,
**kwargs,
)
try:
# Skip any validation in case of forced collection recreate.
if force_recreate:
raise ValueError

collection_exists = client.collection_exists(collection_name)

if collection_exists and force_recreate:
client.delete_collection(collection_name)
collection_exists = False

if collection_exists:
# Get the vector configuration of the existing collection and vector, if it
# was specified. If the old configuration does not match the current one,
# an exception is being thrown.
# an exception is raised.
collection_info = client.get_collection(collection_name=collection_name)
current_vector_config = collection_info.config.params.vectors
if isinstance(current_vector_config, dict) and vector_name is not None:
Expand Down Expand Up @@ -1861,7 +1862,7 @@ async def aconstruct_instance(
f"recreate the collection, set `force_recreate` parameter to "
f"`True`."
)
except (UnexpectedResponse, RpcError, ValueError):
else:
vectors_config = models.VectorParams(
size=vector_size,
distance=models.Distance[distance_func],
Expand All @@ -1875,7 +1876,7 @@ async def aconstruct_instance(
vector_name: vectors_config,
}

client.recreate_collection(
client.create_collection(
collection_name=collection_name,
vectors_config=vectors_config,
shard_number=shard_number,
Expand Down
15 changes: 6 additions & 9 deletions libs/partners/qdrant/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion libs/partners/qdrant/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "langchain-qdrant"
version = "0.1.0"
version = "0.1.1"
description = "An integration package connecting Qdrant and LangChain"
authors = []
readme = "README.md"
Expand Down

0 comments on commit f7bc198

Please sign in to comment.