@ -5,7 +5,18 @@ import uuid
import warnings
import warnings
from hashlib import md5
from hashlib import md5
from operator import itemgetter
from operator import itemgetter
from typing import Any , Callable , Dict , Iterable , List , Optional , Tuple , Type , Union
from typing import (
TYPE_CHECKING ,
Any ,
Callable ,
Dict ,
Iterable ,
List ,
Optional ,
Tuple ,
Type ,
Union ,
)
import numpy as np
import numpy as np
@ -14,7 +25,11 @@ from langchain.embeddings.base import Embeddings
from langchain . vectorstores import VectorStore
from langchain . vectorstores import VectorStore
from langchain . vectorstores . utils import maximal_marginal_relevance
from langchain . vectorstores . utils import maximal_marginal_relevance
MetadataFilter = Dict [ str , Union [ str , int , bool ] ]
if TYPE_CHECKING :
from qdrant_client . http import models as rest
MetadataFilter = Dict [ str , Union [ str , int , bool , dict , list ] ]
class Qdrant ( VectorStore ) :
class Qdrant ( VectorStore ) :
@ -461,18 +476,42 @@ class Qdrant(VectorStore):
metadata = scored_point . payload . get ( metadata_payload_key ) or { } ,
metadata = scored_point . payload . get ( metadata_payload_key ) or { } ,
)
)
def _qdrant_filter_from_dict ( self , filter : Optional [ MetadataFilter ] ) - > Any :
def _build_condition ( self , key : str , value : Any ) - > List [ rest . FieldCondition ] :
if filter is None or 0 == len ( filter ) :
return None
from qdrant_client . http import models as rest
from qdrant_client . http import models as rest
return rest . Filter (
out = [ ]
must = [
if isinstance ( value , dict ) :
for _key , value in value . items ( ) :
out . extend ( self . _build_condition ( f " { key } . { _key } " , value ) )
elif isinstance ( value , list ) :
for _value in value :
if isinstance ( _value , dict ) :
out . extend ( self . _build_condition ( f " { key } [] " , _value ) )
else :
out . extend ( self . _build_condition ( f " { key } " , _value ) )
else :
out . append (
rest . FieldCondition (
rest . FieldCondition (
key = f " { self . metadata_payload_key } . { key } " ,
key = f " { self . metadata_payload_key } . { key } " ,
match = rest . MatchValue ( value = value ) ,
match = rest . MatchValue ( value = value ) ,
)
)
)
return out
def _qdrant_filter_from_dict (
self , filter : Optional [ MetadataFilter ]
) - > Optional [ rest . Filter ] :
from qdrant_client . http import models as rest
if not filter :
return None
return rest . Filter (
must = [
condition
for key , value in filter . items ( )
for key , value in filter . items ( )
for condition in self . _build_condition ( key , value )
]
]
)
)