
    3firG                      U d dl mZ d dlZd dlZd dlZd dlZd dlZd dlmZm	Z	m
Z
mZmZmZmZmZmZmZmZmZ d dlmZ d dlZd dlZd dlmZ d dlmZ d dlmZ d dlm Z  d d	lm!Z!mZm"Z"m#Z#m$Z$m%Z% d d
l&m'Z'm(Z(m)Z)m*Z*m+Z+ d dl,m-Z-m.Z. d dl/m0Z0m1Z1m2Z2m3Z3 d dl4m5Z5m6Z6m7Z7m8Z8m9Z9 d dl:m;Z;  ejx                  de=        G d de>ej~                        Z@e@j                  ZB e6       ZCdZDdaEdeFd<   dddddddZGh dZHddhZIh dZJ eKeG      j                  eI      j                  eJ      j                  eH      ZMd%d&d ZNd'd!ZOd(d"ZPeej                  j\                  e>f   ZR G d# d$e       ZSy))    )annotationsN)AnyAsyncGeneratorCallableDict	GeneratorIterableListOptionalSequenceTupleTypeUnion)cast)Document)
Embeddings)get_from_dict_or_env)VectorStore)SQLColumnExpressionr   create_enginedeletefuncselect)JSONJSONBJSONPATHUUIDinsert)
ConnectionEngine)AsyncEngineAsyncSessionasync_sessionmakercreate_async_engine)Sessiondeclarative_baserelationshipscoped_sessionsessionmaker)maximal_marginal_relevanceoncec                      e Zd ZdZdZdZdZy)DistanceStrategyz&Enumerator of the Distance strategies.l2cosineinnerN)__name__
__module____qualname____doc__	EUCLIDEANCOSINEMAX_INNER_PRODUCT     ]/var/www/auto_recruiter/arenv/lib/python3.12/site-packages/langchain_postgres/vectorstores.pyr-   r-   7   s    0IFr9   r-   	langchainr   _classesz==z!=<z<=>z>=)$eqz$nez$ltz$ltez$gtz$gte>   $in$nin$exists$between$like$ilike>   $or$and$notc                     t         t         S ddlm  G fddt               G  fddt              }|fa t         S )Nr   )Vectorc                  b   e Zd ZdZdZ ej                   ed      dej                        Z ej                  ej                  dd      Z ej                  e      Z edd	d
      Ze	 	 	 	 	 	 dd       Ze	 	 	 	 	 	 d fd       Ze	 d	 	 	 	 	 	 	 dd       Ze	 d	 	 	 	 	 	 	 dd       Zy)8_get_embedding_collection_store.<locals>.CollectionStorezCollection store.langchain_pg_collectionTas_uuid)primary_keydefaultF)nullableuniqueEmbeddingStore
collection)back_populatespassive_deletesc                    |j                  |       j                  t        t        j                  | j
                        |k(        j                         S N)queryfiltertyping_cast
sqlalchemyColumnnamefirst)clssessionr_   s      r:   get_by_namezD_get_embedding_collection_store.<locals>.CollectionStore.get_by_name   s<    
 c"J$5$5sxx@DHIr9   c                   K   |j                  t              j                  t        t        j
                  | j                        |k(               d {   j                         j                         S 7  wrY   )	executer   wherer\   r]   r^   r_   scalarsr`   )ra   rb   r_   CollectionStores      r:   aget_by_namezE_get_embedding_collection_store.<locals>.CollectionStore.aget_by_name   s`      "///55'
(9(9388DL  
s   AA8A6!A8Nc                    d}| j                  ||      }|r||fS  | ||      }|j                  |       |j                          d}||fS )zGet or create a collection.
            Returns:
                 Where the bool is True if the collection was created.
            Fr_   	cmetadataT)rc   addcommitra   rb   r_   rl   createdrU   s         r:   get_or_createzF_get_embedding_collection_store.<locals>.CollectionStore.get_or_create   sY     G$7J!7**$)<JKK
#NNGw&&r9   c                   K   d}| j                  ||       d{   }|r||fS  | ||      }|j                  |       |j                          d{    d}||fS 7 C7 w)z
            Get or create a collection.
            Returns [Collection, bool] where the bool is True if the collection was created.
            FNrk   T)ri   rm   rn   ro   s         r:   aget_or_createzG_get_embedding_collection_store.<locals>.CollectionStore.aget_or_create   ss      G"//>>J!7**$)<JKK
#.."""Gw&& ? #s!   A"A8A"A A" A")rb   r%   r_   strreturnOptional['CollectionStore'])rb   r"   r_   rt   ru   rv   rY   )rb   r%   r_   rt   rl   Optional[dict]ru   Tuple['CollectionStore', bool])rb   r"   r_   rt   rl   rw   ru   rx   )r1   r2   r3   r4   __tablename__r]   r^   r   uuiduuid4Stringr_   r   rl   r'   
embeddingsclassmethodrc   ri   rq   rs   )rh   s   r:   rh   rL   o   sF   1 z  D$**
 !z  !2!2U4P%J%%d+	!' 

 
	!	),	(	 
	 
	&	.1	(	 
	 

 )-		'	' 	' &		'
 ,	' 
	'* 

 )-		'!	' 	' &		'
 ,	' 
	'r9   rh   c                     e Zd ZU dZdZ ej                  ej                  d      Z ej                   e	d       ej                  W  j                   dd            Z eW  d	
      Z ej                   W W             Zded<    ej                  ej                  d      Z ej                  ed      Z ej&                  dddddi      fZy)7_get_embedding_collection_store.<locals>.EmbeddingStorezEmbedding store.langchain_pg_embeddingT)rP   rN   z.uuidCASCADE)ondeleter}   )rV   rJ   	embedding)rR   ix_cmetadata_ginrl   ginjsonb_path_ops)postgresql_usingpostgresql_opsN)r1   r2   r3   r4   ry   r]   r^   r|   idr   
ForeignKeycollection_idr'   rU   r   __annotations__documentr   rl   Index__table_args__)rh   rJ   vector_dimensions   r:   rT   r      s    0Zz00dC)
))!J!!"0017"
 "/,O
-J--f5E.FG	6G$:$$Z%6%6F%J%%ed;	 J"!& +-=>	
r9   rT   )r<   pgvector.sqlalchemyrJ   Base)r   rT   rh   rJ   s   ` @@r:   _get_embedding_collection_storer   h   sB    *U'$ U'n
 
 
: 0HOr9   c                8    | D cg c]  \  }}|	 c}}S c c}}w )z!Return docs from docs and scores.r8   )docs_and_scoresdoc_s      r:   _results_to_docsr      s    -.FCC...s   c                p    t        j                  d      }| j                  |       | j                          y )NzXSELECT pg_advisory_xact_lock(1573678846307946496);CREATE EXTENSION IF NOT EXISTS vector;)r]   textre   rn   )conn	statements     r:   _create_vector_extensionr      s,    	1I 	LLKKMr9   c                     e Zd ZdZddededddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dLdZ	 	 dMdZ	 	 dMdZe	dNd	       Z
dMd
ZdMdZdMdZdMdZdMdZdMdZdMdZdMdZdOdZdPdZdMdZdMdZ	 	 dQ	 	 	 	 	 	 	 dRdZ	 	 dQ	 	 	 	 	 	 	 dRdZdSdZdTdZeddeeddfdd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dUd       Zeddeeddfdd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dUd       Z	 	 dV	 	 	 	 	 	 	 	 	 	 	 dWdZ	 	 dV	 	 	 	 	 	 	 	 	 	 	 dWdZ	 	 dV	 	 	 	 	 	 	 	 	 dXdZ 	 	 dV	 	 	 	 	 	 	 	 	 dXd Z!	 	 dY	 	 	 	 	 	 	 	 	 dZd!Z"	 	 dY	 	 	 	 	 	 	 	 	 dZd"Z#	 	 dY	 	 	 	 	 	 	 d[d#Z$	 	 dY	 	 	 	 	 	 	 d[d$Z%e	d\d%       Z&	 	 dY	 	 	 	 	 	 	 d]d&Z'	 	 dY	 	 	 	 	 	 	 d]d'Z(d^d(Z)	 	 	 	 	 	 d_d)Z*d* Z+	 	 	 	 d`d+Z,dad,Z-	 	 dY	 	 	 	 	 	 	 dbd-Z.	 	 dY	 	 	 	 	 	 	 	 	 dcd.Z/	 	 dY	 	 	 	 	 	 	 	 	 ddd/Z0	 	 dY	 	 	 	 	 	 	 	 	 ddd0Z1e	 deeedddd1	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dfd2       Z2edeeddfdd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dfd3       Z3edeeddd4	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dgd5       Z4edeeddf	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dgd6       Z5eeeddd7	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dhd8       Z6eeeddd7	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dhd9       Z7edid:       Z8edeedddd;	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 djd<       Z9eeeddfdd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dkd=       Z:e	 	 	 	 	 	 	 	 	 	 	 	 	 	 dld>       Z;dmd?Z<	 	 	 	 dn	 	 	 	 	 	 	 	 	 	 	 	 	 dod@Z=	 	 	 	 dn	 	 	 	 	 	 	 	 	 	 	 	 	 dodAZ>	 	 	 	 dn	 	 	 	 	 	 	 	 	 	 	 	 	 dpdBZ?	 	 	 	 dn	 	 	 	 	 	 	 	 	 	 	 	 	 dpdCZ@	 	 	 	 dn	 	 	 	 	 	 	 	 	 	 	 	 	 dqdDZA	 	 	 	 dn	 	 	 	 	 	 	 	 	 	 	 	 	 dqdEZB	 	 	 	 dn	 	 	 	 	 	 	 	 	 	 	 	 	 drdFZC	 	 	 	 dn	 	 	 	 	 	 	 	 	 	 	 	 	 drdGZDeEj                  dsdH       ZGeEj                  dtdI       ZIdudJZJdudKZKy)vPGVectoruS  Postgres vector store integration.

    Setup:
        Install ``langchain_postgres`` and run the docker container.

        .. code-block:: bash

            pip install -qU langchain-postgres
            docker run --name pgvector-container -e POSTGRES_USER=langchain -e POSTGRES_PASSWORD=langchain -e POSTGRES_DB=langchain -p 6024:5432 -d pgvector/pgvector:pg16

    Key init args — indexing params:
        collection_name: str
            Name of the collection.
        embeddings: Embeddings
            Embedding function to use.

    Key init args — client params:
        connection: Union[None, DBConnection, Engine, AsyncEngine, str]
            Connection string or engine.

    Instantiate:
        .. code-block:: python

            from langchain_postgres.vectorstores import PGVector
            from langchain_openai import OpenAIEmbeddings

            # See docker command above to launch a postgres instance with pgvector enabled.
            connection = "postgresql+psycopg://langchain:langchain@localhost:6024/langchain"  # Uses psycopg3!
            collection_name = "my_docs"

            vector_store = PGVector(
                embeddings=OpenAIEmbeddings(model="text-embedding-3-large"),
                collection_name=collection_name,
                connection=connection,
                use_jsonb=True,
            )

    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 [{'bar': 'baz'}]

    Search with filter:
        .. code-block:: python

            results = vector_store.similarity_search(query="thud",k=1,filter={"bar": "baz"})
            for doc in results:
                print(f"* {doc.page_content} [{doc.metadata}]")

        .. code-block:: python

            * thud [{'bar': 'baz'}]

    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.499243] foo [{'baz': 'bar'}]

    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.499243] foo [{'baz': 'bar'}]

    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={'bar': 'baz'}, page_content='thud')]

    NFT)
connectionembedding_lengthcollection_namecollection_metadatadistance_strategypre_delete_collectionloggerrelevance_score_fnengine_args	use_jsonbcreate_extension
async_modec                  || _         || _        || _        || _        || _        || _        || _        |xs t        j                  t              | _
        |	| _        d| _        d| _        d| _        t        |t               r/|rt#        |fi |
xs i | _        n`t%        dd|i|
xs i | _        nIt        |t&              rd| _         || _        n*t        |t(              rd| _         || _        nt+        d      |  | j                   rt-        | j                        | _        n$t1        t3        | j                              | _        || _        || _        |st9        d      | j                   s| j;                          yy)	a  Initialize the PGVector store.
        For an async version, use `PGVector.acreate()` instead.

        Args:
            connection: Postgres connection string or (async)engine.
            embeddings: Any embedding function implementing
                `langchain.embeddings.base.Embeddings` interface.
            embedding_length: The length of the embedding vector. (default: None)
                NOTE: This is not mandatory. Defining it will prevent vectors of
                any other size to be added to the embeddings table but, without it,
                the embeddings can't be indexed.
            collection_name: The name of the collection to use. (default: langchain)
                NOTE: This is not the name of the table, but the name of the collection.
                The tables will be created when initializing the store (if not exists)
                So, make sure the user has the right permissions to create tables.
            distance_strategy: The distance strategy to use. (default: COSINE)
            pre_delete_collection: If True, will delete the collection if it exists.
                (default: False). Useful for testing.
            engine_args: SQLAlchemy's create engine arguments.
            use_jsonb: Use JSONB instead of JSON for metadata. (default: True)
                Strongly discouraged from using JSON as it's not as efficient
                for querying.
                It's provided here for backwards compatibility with older versions,
                and will be removed in the future.
            create_extension: If True, will create the vector extension if it
                doesn't exist. disabling creation is useful when using ReadOnly
                Databases.
        NFurlTzconnection should be a connection string or an instance of sqlalchemy.engine.Engine or sqlalchemy.ext.asyncio.engine.AsyncEngine)bindz'use_jsonb=False is no longer supported.r8   )r   embedding_function_embedding_lengthr   r   _distance_strategyr   logging	getLoggerr1   r   override_relevance_score_fn_engine_async_engine_async_init
isinstancert   r$   r   r    r!   
ValueErrorr#   session_makerr(   r)   r   r   NotImplementedError__post_init__)selfr}   r   r   r   r   r   r   r   r   r   r   r   r   s                 r:   __init__zPGVector.__init__v  sf   Z %",!1.#6 "3%:"; 1 1( ;+=()-48 j#&%8&#.#4"&"  -SS@QrS
F+#DO%DL
K0"DO!+DX  	??!39K9K!LD!/$,,0O!PD" 0%&OPP  r9   c                    | j                   r| j                          t        | j                        \  }}|| _        || _        | j                          | j                          y)zInitialize the store.N)r   create_vector_extensionr   r   rh   rT   create_tables_if_not_existscreate_collectionr   rT   rh   s      r:   r   zPGVector.__post_init__  s[       ((**I""+
'  /,((* r9   c                4  K   | j                   ryd| _         t        | j                        \  }}|| _        || _        | j
                  r| j                          d{    | j                          d{    | j                          d{    y7 57 7 	w)z/Async initialize the store (use lazy approach).NT)	r   r   r   rh   rT   r   acreate_vector_extensionacreate_tables_if_not_existsacreate_collectionr   s      r:   __apost_init__zPGVector.__apost_init__  s      *I""+
'  /,  //111//111%%''' 21's6   ABBB4B5BBBBBc                    | j                   S rY   )r   r   s    r:   r}   zPGVector.embeddings  s    &&&r9   c                    | j                   sJ d       	 | j                   j                         5 }t        |       d d d        y # 1 sw Y   y xY w# t        $ r}t        d|       |d }~ww xY w)Nzengine not foundz#Failed to create vector extension: )r   connectr   	Exception)r   r   es      r:   r   z PGVector.create_vector_extension  so    ||///|	N%%' /4(./ / / 	NA!EFAM	Ns3   A AA A	A A 	A-A((A-c                  K   | j                   sJ d       | j                   j                         4 d {   }|j                  t               d {    d d d       d {    y 7 27 7 	# 1 d {  7  sw Y   y xY ww)Nz_async_engine not found)r   beginrun_syncr   r   r   s     r:   r   z!PGVector.acreate_vector_extension  su     !!<#<<!%%++- 	: 	:-- 8999	: 	: 	:9	: 	: 	: 	:sV   2BA'BA-A)A-B!A+"B)A-+B-A?3A64A?;Bc                    | j                         5 }t        j                  j                  |j	                                |j                          d d d        y # 1 sw Y   y xY wrY   )_make_sync_sessionr   metadata
create_allget_bindrn   r   rb   s     r:   r   z$PGVector.create_tables_if_not_exists  sJ    $$& 	'MM$$W%5%5%78NN	 	 	   >AA!c                0  K   | j                   sJ d       | j                   j                         4 d {   }|j                  t        j                  j
                         d {    d d d       d {    y 7 F7 7 	# 1 d {  7  sw Y   y xY wwN*This method must be called with async_mode)r   r   r   r   r   r   r   s     r:   r   z%PGVector.acreate_tables_if_not_exists
  s~     !!O#OO!%%++- 	: 	:-- 8 8999	: 	: 	:9	: 	: 	: 	:sV   2BA;B-B%A=&B*B5A?6B=B?BBB
BBc                    | j                         5 }t        j                  j                  |j	                                |j                          d d d        y # 1 sw Y   y xY wrY   )r   r   r   drop_allr   rn   r   s     r:   drop_tableszPGVector.drop_tables  sJ    $$& 	'MM""7#3#3#56NN	 	 	r   c                d  K   | j                   sJ d       | j                          d {    | j                   j                         4 d {   }|j                  t        j
                  j                         d {    d d d       d {    y 7 i7 H7 7 # 1 d {  7  sw Y   y xY wwr   )r   r   r   r   r   r   r   r   s     r:   adrop_tableszPGVector.adrop_tables  s     !!O#OO!!!###%%++- 	8 	8-- 6 6777	8 	8 	8 	$	87	8 	8 	8 	8si   'B0B"B0BB0-B=B>BB0BB0B0BB0B-!B$"B-)B0c                
   | j                   r| j                          | j                         5 }| j                  j	                  || j
                  | j                         |j                          d d d        y # 1 sw Y   y xY wN)rl   )r   delete_collectionr   rh   rq   r   r   rn   r   s     r:   r   zPGVector.create_collection  sr    %%""$$$& 	'  ..--9Q9Q /  NN		 	 	s   AA99Bc                  K   | j                          d {    | j                         4 d {   }| j                  r| j                  |       d {    | j                  j                  || j                  | j                         d {    |j                          d {    d d d       d {    y 7 7 7 k7 37 7 # 1 d {  7  sw Y   y xY wwr   )	r   _make_async_sessionr   _adelete_collectionrh   rs   r   r   rn   r   s     r:   r   zPGVector.acreate_collection#  s     !!###++- 	# 	#))..w777&&55--9Q9Q 6    .."""	# 	# 	# 	$	#7 #	# 	# 	# 	#s   CB<CB>C!CC 9CCC&C'C+C6C7C>C CCCCCCCCc                    | j                  |      }|s| j                  j                  d       y |j                  |       y NCollection not found)get_collectionr   warningr   r   rb   rU   s      r:   _delete_collectionzPGVector._delete_collection-  s7    ((1
KK 67z"r9   c                   K   | j                  |       d {   }|s| j                  j                  d       y |j                  |       d {    y 7 <7 wr   )aget_collectionr   r   r   r   s      r:   r   zPGVector._adelete_collection4  sO     //88
KK 67nnZ(((	 9 	)s!   AA6AAAAc                    | j                         5 }| j                  |      }|s%| j                  j                  d       	 d d d        y |j	                  |       |j                          d d d        y # 1 sw Y   y xY wr   )r   r   r   r   r   rn   r   s      r:   r   zPGVector.delete_collection;  sp    $$& 	',,W5J##$:;		 	
 NN:&NN	 	 	s   0A4
!A44A=c                  K   | j                          d {    | j                         4 d {   }| j                  |       d {   }|s-| j                  j	                  d       	 d d d       d {    y |j                  |       d {    |j                          d {    d d d       d {    y 7 7 7 y7 M7 57 7 # 1 d {  7  sw Y   y xY wwr   )r   r   r   r   r   r   rn   r   s      r:   adelete_collectionzPGVector.adelete_collectionD  s     !!###++- 	# 	##33G<<J##$:;		# 	# 	#
 ..,,,.."""	# 	# 	# 	$	#<	#
 -"	# 	# 	# 	#s   C!B>C!C C!CC	"C+C!6C7C!<CCC(C)C-C!8C
9C! C!CC!CC
C!CCCC!c                4   | j                         5 }|| j                  j                  d       t        | j                        }|rj| j                  |      }|s%| j                  j                  d       	 ddd       y|j                  | j                  j                  |j                  k(        }|j                  | j                  j                  j                  |            }|j                  |       |j                          ddd       y# 1 sw Y   yxY w)zDelete vectors by ids or uuids.

        Args:
            ids: List of ids to delete.
            collection_only: Only delete ids in the collection.
        NUTrying to delete vectors by ids (represented by the model using the custom ids field)r   )r   r   debugr   rT   r   r   rf   r   rz   r   in_re   rn   r   idscollection_onlykwargsrb   stmtrU   s          r:   r   zPGVector.deleteN  s     $$& 	'!!2
 d112"!%!4!4W!=J%++,BC	 	  ::++99Z__LD zz$"5"5"8"8"<"<S"AB%NN+	 	 	s   A$D>BDDc                  K   | j                          d{    | j                         4 d{   }|| j                  j                  d       t	        | j
                        }|rz| j                  |       d{   }|s-| j                  j                  d       	 ddd      d{    y|j                  | j
                  j                  |j                  k(        }|j                  | j
                  j                  j                  |            }|j                  |       d{    |j                          d{    ddd      d{    y7 B7 ,7 7 7 77 !7 # 1 d{  7  sw Y   yxY ww)zAsync delete vectors by ids or uuids.

        Args:
            ids: List of ids to delete.
            collection_only: Only delete ids in the collection.
        Nr   r   )r   r   r   r   r   rT   r   r   rf   r   rz   r   r   re   rn   r   s          r:   adeletezPGVector.adeleteq  sV     !!###++- 	# 	#!!2
 d112"'+';';G'D!DJ%++,BC	# 	# 	#  ::++99Z__LD zz$"5"5"8"8"<"<S"ABood+++.."""+	# 	# 	# 	$	# "E	#( ,"+	# 	# 	# 	#s   E=EE=EE=A	E(<E="E(E=*E +E=0A:E(*E"+E(E$E(E=E&E=E=E( E="E($E(&E=(E:.E1/E:6E=c                t    | j                   rJ d       | j                  j                  || j                        S )N-This method must be called without async_mode)r   rh   rc   r   r   s     r:   r   zPGVector.get_collection  s6    %%V'VV%##//9M9MNNr9   c                   K   | j                   sJ d       | j                          d {    | j                  j                  || j                         d {   S 7 27 wr   )r   r   rh   ri   r   r   s     r:   r   zPGVector.aget_collection  sX     !!O#OO!!!###))66w@T@TUUU 	$Us!   'A A-A AA A )r   c
          
         |*|D cg c]  }t        t        j                               ! }}|s|D cg c]  }i  }} | d|||||	|
d|} |j                  d||||d| |S c c}w c c}w )N)r   r   r}   r   r   r   textsr}   	metadatasr   r8   )rt   rz   r{   add_embeddingsra   r  r}   r   r  r   r   r   r   r   r   r   r   stores                 r:   __fromzPGVector.__from  s      ;.343tzz|$4C4%*++I+ 
!+ /"7
 
 	 	
J)	
PV	
 ' 5 ,s
   $A&	A+c
                  K   |*|D cg c]  }t        t        j                               ! }}|s|D cg c]  }i  }} | d|||||	|
dd|} |j                  d||||d| d {    |S c c}w c c}w 7 w)NT)r   r   r}   r   r   r   r   r  r8   )rt   rz   uuid1aadd_embeddingsr  s                 r:   __afromzPGVector.__afrom  s       ;.343tzz|$4C4%*++I+ 	
!+ /"7	
 	
 $e## 
J)
PV
 	
 	
 ) 5 ,	
s%   A=$A1A=	A6,A=*A;+A=c                `   | j                   rJ d       |+|D cg c]  }t        t        j                               ! }}n.|D cg c]#  }||nt        t        j                               % }}|s|D cg c]  }i  }}| j	                         5 }	| j                  |	      }
|
st        d      t        ||||      D cg c]  \  }}}}||
j                  |||xs i d }}}}}t        | j                        j                  |      }|j                  dg|j                  j                  |j                  j                  |j                  j                  d      }|	j!                  |       |	j#                          ddd       |S c c}w c c}w c c}w c c}}}}w # 1 sw Y   |S xY w)a  Add embeddings to the vectorstore.

        Args:
            texts: Iterable of strings to add to the vectorstore.
            embeddings: List of list of embedding vectors.
            metadatas: List of metadatas associated with the texts.
            ids: Optional list of ids for the documents.
                 If not provided, will generate a new id for each document.
            kwargs: vectorstore specific parameters
        z)This method must be called with sync_modeNr   r   r   r   r   rl   r   r   r   rl   index_elementsset_)r   rt   rz   r{   r   r   r   zipr   rT   valueson_conflict_do_updateexcludedr   r   rl   re   rn   r   r  r}   r  r   r   r   ids_r   rb   rU   r   r   r   datar   on_conflict_stmts                    r:   r  zPGVector.add_embeddings  s   $ %%R'RR%;/45!C

%5D5JMNB".Bc$**,.??NDN%*++I+$$& 	',,W5J !788 699j$6  2D(Ir %/__!* $!)RD  $--.55d;D#99 $v "&!8!8 $ 6 6!%!8!8  :   OO,-NN7	: I 6N ,		: s0   $F(F5	F2F#"F$BF#F##F-c                  K   | j                          d{    |+|D cg c]  }t        t        j                               ! }}n.|D cg c]#  }||nt        t        j                               % }}|s|D cg c]  }i  }}| j	                         4 d{   }	| j                  |	       d{   }
|
st        d      t        ||||      D cg c]  \  }}}}||
j                  |||xs i d }}}}}t        | j                        j                  |      }|j                  dg|j                  j                  |j                  j                  |j                  j                  d      }|	j!                  |       d{    |	j#                          d{    ddd      d{    |S 7 c c}w c c}w c c}w 7 27 c c}}}}w 7 N7 87 *# 1 d{  7  sw Y   |S xY ww)a  Async add embeddings to the vectorstore.

        Args:
            texts: Iterable of strings to add to the vectorstore.
            embeddings: List of list of embedding vectors.
            metadatas: List of metadatas associated with the texts.
            ids: Optional list of ids for the texts.
                 If not provided, will generate a new id for each text.
            kwargs: vectorstore specific parameters
        Nr   r  r   r  r  )r   rt   rz   r{   r   r   r   r  r   rT   r  r  r  r   r   rl   re   rn   r  s                    r:   r  zPGVector.aadd_embeddings%  s    $ !!###;/45!C

%5D5JMNB".Bc$**,.??NDN%*++I+++- 	# 	##33G<<J !788 699j$6  2D(Ir %/__!* $!)RD  $--.55d;D#99 $v "&!8!8 $ 6 6!%!8!8  :   //"2333.."""7	# 	#: O 	$ 6N ,	#<, 4"7	# 	# 	# 	#: s   G7F;
G7$F>G7(G4G7<	GG7GG7G!4G5$G!"G;BG!GG!$G%G!)G74G5G7>G7G!	G!G!G7!G4'G*(G4/G7c           	         | j                   rJ d       t        |      }| j                  j                  |      } | j                  d|t        |      |rt        |      nd|rt        |      ndd|S )  Run more texts through the embeddings and add to the vectorstore.

        Args:
            texts: Iterable of strings to add to the vectorstore.
            metadatas: Optional list of metadatas associated with the texts.
            ids: Optional list of ids for the texts.
                 If not provided, will generate a new id for each text.
            kwargs: vectorstore specific parameters

        Returns:
            List of ids from adding the texts into the vectorstore.
        r  Nr  r8   )r   listr   embed_documentsr  r   r  r  r   r   texts_r}   s          r:   	add_textszPGVector.add_texts`  s}    & %%V'VV%e,,<<VD
"t"" 
J')2d9o S	d	

 
 	
r9   c           	     &  K   | j                          d{    t        |      }| j                  j                  |       d{   } | j                  d|t        |      |rt        |      nd|rt        |      ndd| d{   S 7 t7 H7 w)r  Nr  r8   )r   r   r   aembed_documentsr  r"  s          r:   
aadd_textszPGVector.aadd_texts~  s     & !!###e22CCFKK
)T)) 
J')2d9o S	d	

 
 
 	
 	$K
s4   BB-BBABBBBBc                    | j                   rJ d       | j                  j                  |      }| j                  |||      S )^  Run similarity search with PGVector with distance.

        Args:
            query (str): Query text to search for.
            k (int): Number of results to return. Defaults to 4.
            filter (Optional[Dict[str, str]]): Filter by metadata. Defaults to None.

        Returns:
            List of Documents most similar to the query.
        r  r   kr[   )r   r}   embed_querysimilarity_search_by_vectorr   rZ   r+  r[   r   r   s         r:   similarity_searchzPGVector.similarity_search  sN    " %%V'VV%OO//6	// 0 
 	
r9   c                   K   | j                          d{    | j                  j                  |       d{   }| j                  |||       d{   S 7 C7 "7 w)r)  Nr*  )r   r}   aembed_queryasimilarity_search_by_vectorr.  s         r:   asimilarity_searchzPGVector.asimilarity_search  sf     " !!###//66u==	66 7 
 
 	
 	$=
s1   A A"A AA AA A A c                    | j                   rJ d       | j                  j                  |      }| j                  |||      }|S )c  Return docs most similar to query.

        Args:
            query: Text to look up documents similar to.
            k: Number of Documents to return. Defaults to 4.
            filter (Optional[Dict[str, str]]): Filter by metadata. Defaults to None.

        Returns:
            List of Documents most similar to the query and score for each.
        r  r*  )r   r}   r,  &similarity_search_with_score_by_vectorr   rZ   r+  r[   r   docss         r:   similarity_search_with_scorez%PGVector.similarity_search_with_score  sP      %%V'VV%OO//6	::1V ; 
 r9   c                   K   | j                          d{    | j                  j                  |       d{   }| j                  |||       d{   }|S 7 E7 $7 
w)r5  Nr*  )r   r}   r1  'asimilarity_search_with_score_by_vectorr7  s         r:   asimilarity_search_with_scorez&PGVector.asimilarity_search_with_score  si       !!###//66u==	AA1V B 
 
  	$=
s1   A"A"A"AA"A A"A" A"c                   | j                   t        j                  k(  r | j                  j                  j
                  S | j                   t        j                  k(  r | j                  j                  j                  S | j                   t        j                  k(  r | j                  j                  j                  S t        d| j                    ddj                  t        D cg c]  }|j                   c}       d      c c}w )Nz#Got unexpected value for distance: z. Should be one of z, .)r   r-   r5   rT   r   l2_distancer6   cosine_distancer7   max_inner_productr   joinvalue)r   dss     r:   r   zPGVector.distance_strategy  s    ""&6&@&@@&&00<<<$$(8(?(??&&00@@@$$(8(J(JJ&&00BBB5d6M6M5N O$$(IIBR.SBrxx.S$T#UUVX .Ss   C?c                r    | j                   rJ d       | j                  |||      }| j                  |      S )Nr  r*  )r   _PGVector__query_collection_results_to_docs_and_scores)r   r   r+  r[   resultss        r:   r6  z/PGVector.similarity_search_with_score_by_vector
  sA     %%V'VV%))I6)R//88r9   c                $  K   | j                          d {    | j                         4 d {   }| j                  ||||       d {   }| j                  |      cd d d       d {    S 7 \7 E7 *7 # 1 d {  7  sw Y   y xY ww)Nrb   r   r+  r[   )r   r   _PGVector__aquery_collectionrG  )r   r   r+  r[   rb   rH  s         r:   r;  z0PGVector.asimilarity_search_with_score_by_vector  s      !!###++- 	= 	= 449& 5  G 33G<	= 	= 	= 	$	=	= 	= 	= 	=sf   BA3BA5BA;A7A;!B-A9.B5B7A;9B;BBB	Bc                   |D cg c]o  }t        t        |j                  j                        |j                  j                  |j                  j
                        | j                  |j                  ndfq }}|S c c}w )z$Return docs and scores from results.r   page_contentr   N)r   rt   rT   r   r   rl   r}   distance)r   rH  resultr8  s       r:   rG  z$PGVector._results_to_docs_and_scores#  s     "

  600334!'!6!6!?!?#22<<
 $(??#>D

 

 

s   A4A=c           
     :   t        |t              st        dt        |       d|       |j	                  d      rt        d|       |j                         st        d| d      t        |t              r~t        |      dk7  r4t        dt        |       d	t        |j                               d
d        t        |j                               d   \  }}|t        vrt        d| dt               d}|}|t        v rYt        |   }t        j                  | j                  j                   t#        d| d| dt$              t#        d|it&                    S |dk(  r|\  }}t        j                  | j                  j                   t#        d| dt$              t#        d|it&                    }t        j                  | j                  j                   t#        d| dt$              t#        d|it&                    }	t)        j*                  ||	      S |dv r|dv rf|D ]a  }
t        |
t        t,        t.        f      st1        dt        |
       d|
       t        |
t2              sIt1        dt        |
       d|
        | j                  j                   |   j4                  }|dv r(|j7                  |D 
cg c]  }
t        |
       c}
      S |dv r)|j7                  |D 
cg c]  }
t        |
       c}
       S |dv r|j9                  |      S |dv r|j;                  |      S t1               |dk(  rOt        |t2              st        d |       t        j<                  | j                  j                   |      }|r|S | S t1               c c}
w c c}
w )!a  Create a filter for a specific field.

        Args:
            field: name of field
            value: value to filter
                If provided as is then this will be an equality filter
                If provided as a dictionary then this will be a filter, the key
                will be the operator and the value will be the value to filter by

        Returns:
            sqlalchemy expression
        z"field should be a string but got: z with value: $z@Invalid filter condition. Expected a field but got an operator: zInvalid field name: z. Expected a valid identifier.   zInvalid filter condition. Expected a value which is a dictionary with a single key that corresponds to an operator but got a dictionary with z keys. The first few keys are: N   r   zInvalid operator: z. Expected one of r?   z$. z $valuerC  rC   z
 >= $valuez
 <= $value>   r@   rA   rD   rE   >   r@   rA   zUnsupported type:  for value: >   r@   >   rA   >   rD   >   rE   rB   z8Expected a boolean value for $exists operator, but got: )r   rt   r   type
startswithisidentifierdictlenr   keysitemsSUPPORTED_OPERATORSCOMPARISONS_TO_NATIVEr   jsonb_path_matchrT   rl   r   r   r   r]   and_intfloatr   boolastextr   likeilikejsonb_exists)r   fieldrC  operatorfilter_valuenativelowhighlower_boundupper_boundvalqueried_field	conditions                r:   _handle_field_filterzPGVector._handle_field_filter2  s   " %%4T%[MugV  C R'  !!#&ug-KL  eT"5zQ 114U =!!%ejjl!3BQ!7 8:  &*%++-%8%;"Hl22 (
 3'':&;= 
 H L,, +84F((##--r%&18<g|,e4 
 #$IC//##--r%
+X6gs^U+K
 //##--r%
+X6gt_e,K
 ??;<<;;?*' 	C%cCe+<=10c<uM  "#t,10c<uM 	 !//99%@GGM7"$((l)Ks#c()KLLX%%))|*L3s8*LMMMY&$)),77Z'$**<88)++"lD1 **69  ))##--I !-9<9*<%''+ *L*Ls   ;N'Nc                   d\  }}}}}}d\  }	}
}}}|j                         D ci c]  \  }}|j                         | }}}|t        t        j                  |      v r7| j                  j
                  |   j                  j                  ||         }|S |t        t        j                  |      v r7| j                  j
                  |   j                  j                  ||         }|S |t        t        j                  |      v rS| j                  j
                  |   j                  j                  t        ||   d         t        ||   d               }|S |t        t        j                  |      v r4| j                  j
                  |   j                  t        ||         kD  }|S |t        t        j                  |      v r4| j                  j
                  |   j                  t        ||         k  }|S |t        t        j                  |      v r4| j                  j
                  |   j                  t        ||         k7  }|S |	t        t        j                  |      v r4| j                  j
                  |   j                  t        ||	         k(  }|S |
t        t        j                  |      v r7| j                  j
                  |   j                  j                  ||
         }|S |t        t        j                  |      v r7| j                  j
                  |   j                  j                  ||         }|S |t        t        j                  |      v r6||   D cg c]  }| j                  ||       }}t        j                  | }|S |t        t        j                  |      v r6||   D cg c]  }| j                  ||       }}t        j                  | }|S d}|S c c}}w c c}w c c}w )aK  Deprecated functionality.

        This is for backwards compatibility with the JSON based schema for metadata.
        It uses incorrect operator syntax (operators are not prefixed with $).

        This implementation is not efficient, and has bugs associated with
        the way that it handles numeric filter clauses.
        )inninbetweengtltne)eqrf  containsorandr   rS  N)r]  lowermaprt   rT   rl   re  r   not_inrx  rf  r}  _create_filter_clauser]   or_ra  )r   keyrC  INNINBETWEENGTLTNEEQLIKECONTAINSORANDr+  vvalue_case_insensitivefilter_by_metadata	sub_value
or_clausesand_clausess                        r:    _create_filter_clause_deprecatedz)PGVector._create_filter_clause_deprecated  s    (P$C"b"&K#D(B;@;;=!I41a!'')Q,!I!ISYY&&!%!4!4!>!>s!C!J!J!N!N&r*"h "!c C		5))!%!4!4!>!>s!C!J!J!Q!Q&s+"` "![ CIIu--!%!4!4!>!>s!C!J!J!R!R*73A67*73A67"X "!Q 3syy%((!%!4!4!>!>s!C!J!JS&r*N "N "!I 3syy%((!%!4!4!>!>s!C!J!JS&r*N "F "!A 3syy%((!%!4!4!>!>s!C!J!Jc&r*O "> "!9 3syy%((!%!4!4!>!>s!C!J!Jc&r*O "6 "!1 SE**!%!4!4!>!>s!C!J!J!O!O&t,". "!) SYY..!%!4!4!>!>s!C!J!J!S!S&x0"& "!! 3syy%(( "8!; **3	:J  ",!< "! C		5)) "8!< **3	:K  ",+!>
 "! "&!!m "JNs   O&!O,3O1c                (   g }|j                         D ]|  \  }}t        |t              r'| j                  ||      }|+|j	                  |       =| j
                  j                  |   j                  t        |      k(  }|j	                  |       ~ |S )a&  Convert filters from IR to SQL clauses.

        **DEPRECATED** This functionality will be deprecated in the future.

        It implements translation of filters for a schema that uses JSON
        for metadata rather than the JSONB field which is more efficient
        for querying.
        )	r]  r   rZ  r  appendrT   rl   re  rt   )r   r[   filter_clausesr  rC  r  s         r:   %_create_filter_clause_json_deprecatedz.PGVector._create_filter_clause_json_deprecated  s      ,,. 
	:JC%&%)%J%J3PU%V"%1"))*<=%)%8%8%B%B3%G%N%NRUS &" %%&89
	: r9   c                   t        |t              r4t        |      dk(  rht        |j	                               d   \  }}|j                  d      r |j                         dvr#t        d|       | j                  |||         S |j                         dk(  rt        |t              st        dt        |       d|       |D cg c]  }| j                  |       }}t        |      dkD  rt        j                  | S t        |      dk(  r|d   S t        d	      |j                         d
k(  rt        |t              st        dt        |       d|       |D cg c]  }| j                  |       }}t        |      dkD  rt        j                  | S t        |      dk(  r|d   S t        d	      |j                         dk(  rt        |t              rS|D cg c]  }| j                  |       }}t        j                  |D 	cg c]  }	t        j                  |	       c}	 }
|
S t        |t              r&| j                  |      }
t        j                  |
      S t        dt        |             t        d|       t        |      dkD  r|j                         D ]!  }|j                  d      st        d|        |j	                         D cg c]  \  }}| j                  ||       }}}t        |      dkD  rt        j                  | S t        |      dk(  r|d   S t        d	      t        d      t        dt        |             c c}w c c}w c c}w c c}	w c c}}w )a  Convert LangChain IR filter representation to matching SQLAlchemy clauses.

        At the top level, we still don't know if we're working with a field
        or an operator for the keys. After we've determined that we can
        call the appropriate logic to handle filter creation.

        Args:
            filters: Dictionary of filters to apply to the query.

        Returns:
            SQLAlchemy clause to apply to the query.
        rS  r   rR  )rG   rF   rH   z>Invalid filter condition. Expected $and, $or or $not but got: rG   zExpected a list, but got rV  zKInvalid filter condition. Expected a dictionary but got an empty dictionaryrF   rH   zCInvalid filter condition. Expected a dictionary or a list but got: z4Invalid filter condition. Expected a field but got: z$Got an empty dictionary for filters.z2Invalid type: Expected a dictionary but got type: )r   rZ  r[  r   r]  rX  r  r   rt  rW  r  r]   ra  r  not_r\  )r   filtersr  rC  elra  r  itemnot_conditionsrs  r  r+  r  s                r:   r  zPGVector._create_filter_clause  s    gt$7|q  "'--/215
U>>#&yy{*AA(((+u.   44S'#,GG99;&(%eT2(7U}LQVPWX  FKKrD66r:KDK4y1})55Ta#Aw(:  YY[E)%eT2(7U}LQVPWX  EJJb455b9JCJ3x!|)~~s33SQ"1v(:  YY[F*!%.IN*AED66t<* *  * 2@$- !+	 :   $#E40#99%@)t44(226u+@ 
 %$$'5*  W!"<<> C~~c*(RSVRWX  ELMMOTDAq11!Q7TTt9q=%??D11Y!^7N$6 
 !!GHHDT']OT O L K*6 Us   M M"M'M,M1c                .   | j                         5 }| j                  |      }|st        d      | j                  j                  |j
                  k(  g}|rS| j                  r%| j                  |      }|4|j                  |       n"| j                  |      }|j                  |       | j                  } |j                  | j                  | j                  |      j                  d            j                  | j                  t!        j"                  d            j%                  | j&                  | j                  j                  | j&                  j
                  k(        j)                  |      j+                         }	ddd       |	S # 1 sw Y   	S xY w)Query the collection.r   NrO  )r   r   r   rT   r   rz   r   r  r  r  extendrZ   r   labelr[   order_byr]   ascrB  rh   limitall)
r   r   r+  r[   rb   rU   	filter_byr  _typerH  s
             r:   __query_collectionzPGVector.__query_collectionr  sh    $$& 	',,W5J !788,,::jooMNI>>%)%?%?%GN%1!((8 &*%O%OPV%WN$$^4''E''**95;;JG 	$
 *..45((''559M9M9R9RR q %	B C	B s   E/F

Fc                  K   | j                         4 d{   }| j                  |       d{   }|st        d      | j                  j                  |j
                  k(  g}|rS| j                  r%| j                  |      }|4|j                  |       n"| j                  |      }|j                  |       | j                  } t        | j                  | j                  |      j                  d            j                  | j                  t!        j"                  d            j%                  | j&                  | j                  j                  | j&                  j
                  k(        j)                  |      }	|j+                  |	       d{   j-                         }
|
cddd      d{    S 7 7 7 +7 # 1 d{  7  sw Y   yxY ww)r  Nr   rO  )r   r   r   rT   r   rz   r   r  r  r  r  r   r   r  r[   r  r]   r  rB  rh   r  re   r  )r   rb   r   r+  r[   rU   r  r  r  r   rH  s              r:   __aquery_collectionzPGVector.__aquery_collection  s     ++- "	 "	#33G<<J !788,,::jooMNI>>%)%?%?%GN%1!((8 &*%O%OPV%WN$$^4''E''**95;;JG 	$
 *..45((''559M9M9R9RR q  -4OOD,A&A%F%F%HGE"	 "	 "	<> 'BA"	 "	 "	 "	sg   GF8GGF;E!GF>G&G2G 3G;G>G GGG	GGc                f    | j                   rJ d       | j                  |||      }t        |      S )k  Return docs most similar to embedding vector.

        Args:
            embedding: Embedding to look up documents similar to.
            k: Number of Documents to return. Defaults to 4.
            filter (Optional[Dict[str, str]]): Filter by metadata. Defaults to None.

        Returns:
            List of Documents most similar to the query vector.
        r  r*  )r   r6  r   r   r   r+  r[   r   r   s         r:   r-  z$PGVector.similarity_search_by_vector  sC    " %%V'VV%EE1V F 
  00r9   c                   K   | j                   sJ d       | j                          d{    | j                  |||       d{   }t        |      S 7 +7 w)r  r   Nr*  )r   r   r;  r   r  s         r:   r2  z%PGVector.asimilarity_search_by_vector  si     " !!O#OO!!!### $ L L1V !M !
 
  00	 	$
s!   'AAAAAA)r   r   r   r   r   c          
     n    |j                  t        |            }
 | j                  ||
|f||||||d|	S )=Return VectorStore initialized from documents and embeddings.r  r   r   r   r   r   )r!  r   _PGVector__fromra   r  r   r  r   r   r   r   r   r   r}   s              r:   
from_textszPGVector.from_texts  sW     ..tE{;
szz
  +/"7
 
 	
r9   c          
        K   |j                  t        |             d{   }
 | j                  ||
|f||||||d|	 d{   S 7 (7 w)r  Nr  )r&  r   _PGVector__afromr  s              r:   afrom_textszPGVector.afrom_texts  so      %55d5kBB
 S[[
  +/"7
 
 
 	
 C
s!   AA	#AAAA)r  r   r   r   r   c          	         |D 	cg c]  }	|	d   	 }
}	|D 	cg c]  }	|	d   	 }}	 | j                   |
||f|||||d|S c c}	w c c}	w )a  Construct PGVector wrapper from raw documents and embeddings.

        Args:
            text_embeddings: List of tuples of text and embeddings.
            embedding: Embeddings object.
            metadatas: Optional list of metadatas associated with the texts.
            collection_name: Name of the collection.
            distance_strategy: Distance strategy to use.
            ids: Optional list of ids for the documents.
                 If not provided, will generate a new id for each document.
            pre_delete_collection: If True, will delete the collection if it exists.
                **Attention**: This will delete all the documents in the existing
                collection.
            kwargs: Additional arguments.

        Returns:
            PGVector: PGVector instance.

        Example:
            .. code-block:: python

                from langchain_postgres.vectorstores import PGVector
                from langchain_openai.embeddings import OpenAIEmbeddings

                embeddings = OpenAIEmbeddings()
                text_embeddings = embeddings.embed_documents(texts)
                text_embedding_pairs = list(zip(texts, text_embeddings))
                vectorstore = PGVector.from_embeddings(text_embedding_pairs, embeddings)
        r   rS  r  r   r   r   r   )r  ra   text_embeddingsr   r  r   r   r   r   r   tr  r}   s               r:   from_embeddingszPGVector.from_embeddings2  sw    T  //!1//$34qad4
4szz

  +/"7

 

 
	
 04s
   A Ac           	        K   |D 	cg c]  }	|	d   	 }
}	|D 	cg c]  }	|	d   	 }}	 | j                   |
||f|||||d| d{   S c c}	w c c}	w 7 w)a  Construct PGVector wrapper from raw documents and pre-
        generated embeddings.

        Return VectorStore initialized from documents and embeddings.
        Postgres connection string is required
        "Either pass it as a parameter
        or set the PGVECTOR_CONNECTION_STRING environment variable.

        Example:
            .. code-block:: python

                from langchain_community.vectorstores import PGVector
                from langchain_community.embeddings import OpenAIEmbeddings
                embeddings = OpenAIEmbeddings()
                text_embeddings = embeddings.embed_documents(texts)
                text_embedding_pairs = list(zip(texts, text_embeddings))
                faiss = PGVector.from_embeddings(text_embedding_pairs, embeddings)
        r   rS  r  N)r  r  s               r:   afrom_embeddingszPGVector.afrom_embeddingsk  s     <  //!1//$34qad4
4 S[[

  +/"7

 

 

 
	
 04

s%   AA
AA AAA)r   r   r   r   c          	     "     | d|||||d|}|S )
        Get instance of an existing PGVector store.This method will
        return the instance of the store without inserting any new
        embeddings
        )r   r   r}   r   r   r8   r8   ra   r   r   r   r   r   r   r	  s           r:   from_existing_indexzPGVector.from_existing_index  s3       
!+ /"7
 
 r9   c          
     2   K   t        d|||||dd|}|S w)r  T)r   r   r}   r   r   r   r8   )r   r  s           r:   afrom_existing_indexzPGVector.afrom_existing_index  s:        
!+ /"7
 
 s   c                <    t        |dd      }|st        d      |S )Nr   PGVECTOR_CONNECTION_STRING)r  r  env_keyz~Postgres connection string is requiredEither pass it as a parameteror set the PGVECTOR_CONNECTION_STRING environment variable.)r   r   )ra   r   connection_strings      r:   get_connection_stringzPGVector.get_connection_string  s6    !50"
 !N  ! r9   )r   r   r   r   r   r   c                   |D 
cg c]  }
|
j                    }}
|D 
cg c]  }
|
j                   }}
 | j                  d|||||||||d	|	S c c}
w c c}
w )r  )	r  r   r   r   r  r   r   r   r   r8   )rN  r   r  )ra   	documentsr   r   r   r   r   r   r   r   dr  r  s                r:   from_documentszPGVector.from_documents  sw      *33A33)23AQZZ3	3s~~ 
"7/!+
 
 	
 43s
   AAc                  K   |D 	cg c]  }	|	j                    }
}	|D 	cg c]  }	|	j                   }}	| j                  |      }||d<    | j                  d|
|||||||d| d{   S c c}	w c c}	w 7 w)z
        Return VectorStore initialized from documents and embeddings.
        Postgres connection string is required
        "Either pass it as a parameter
        or set the PGVECTOR_CONNECTION_STRING environment variable.
        r   )r  r   r   r   r  r   r   r   Nr8   )rN  r   r  r  )ra   r  r   r   r   r   r   r   r   r  r  r  r  s                r:   afrom_documentszPGVector.afrom_documents   s     ( *33A33)23AQZZ3	355f=0|$S__ 

"7/+

 

 

 
	
 43


s%   A:A.A:A36A:)A8*A:c                J    |dk7  rt        d      d| d| d| d| d| d| S )z2Return connection string from database parameters.psycopgz!Only psycopg3 driver is supportedzpostgresql+z://:@/)r   )ra   driverhostportdatabaseuserpasswords          r:    connection_string_from_db_paramsz)PGVector.connection_string_from_db_params&  sC     Y%&IJJVHCvQxj$qazRRr9   c                Z   | j                   | j                   S | j                  t        j                  k(  r| j                  S | j                  t        j
                  k(  r| j                  S | j                  t        j                  k(  r| j                  S t        d| j                   d      )a8  
        The 'correct' relevance function
        may differ depending on a few things, including:
        - the distance / similarity metric used by the VectorStore
        - the scale of your embeddings (OpenAI's are unit normed. Many others are not!)
        - embedding dimensionality
        - etc.
        z=No supported normalization function for distance_strategy of z?.Consider providing relevance_score_fn to PGVector constructor.)
r   r   r-   r6   _cosine_relevance_score_fnr5   _euclidean_relevance_score_fnr7   %_max_inner_product_relevance_score_fnr   r   s    r:   _select_relevance_score_fnz#PGVector._select_relevance_score_fn5  s     ++7333 ""&6&=&==222$$(8(B(BB555$$(8(J(JJ===--1-D-D,E FQQ r9   c                x   | j                   rJ d       | j                  |||      }|D cg c]  }|j                  j                   }	}t	        t        j                  |t
        j                        |	||      }
| j                  |      }t        |      D cg c]  \  }}||
v s| c}}S c c}w c c}}w )  Return docs selected using the maximal marginal relevance with score
            to embedding vector.

        Maximal marginal relevance optimizes for similarity to query AND diversity
            among selected documents.

        Args:
            embedding: Embedding to look up documents similar to.
            k (int): Number of Documents to return. Defaults to 4.
            fetch_k (int): Number of Documents to fetch to pass to MMR algorithm.
                Defaults to 20.
            lambda_mult (float): Number between 0 and 1 that determines the degree
                of diversity among the results with 0 corresponding
                to maximum diversity and 1 to minimum diversity.
                Defaults to 0.5.
            filter (Optional[Dict[str, str]]): Filter by metadata. Defaults to None.

        Returns:
            List[Tuple[Document, float]]: List of Documents selected by maximal marginal
                relevance to the query and score for each.
        r  r*  dtyper+  lambda_mult)
r   rF  rT   r   r*   nparrayfloat32rG  	enumerate)r   r   r+  fetch_kr  r[   r   rH  rP  embedding_listmmr_selected
candidatesirs                 r:   2max_marginal_relevance_search_with_score_by_vectorz;PGVector.max_marginal_relevance_search_with_score_by_vectorP  s    < %%V'VV%))IQW)XHOPf&//99PP1HHYbjj1#	
 55g>
'
3IdaqL7HII Q Js   B1B6)B6c                *  K   | j                          d{    | j                         4 d{   }| j                  ||||       d{   }|D 	cg c]  }	|	j                  j                   }
}	t        t        j                  |t        j                        |
||      }| j                  |      }t        |      D cg c]  \  }}||v s| c}}cddd      d{    S 7 7 7 c c}	w c c}}w 7 # 1 d{  7  sw Y   yxY ww)r  NrJ  r  r  )r   r   rK  rT   r   r*   r  r  r  rG  r  )r   r   r+  r  r  r[   r   rb   rH  rP  r  r  r  r  r  s                  r:   3amax_marginal_relevance_search_with_score_by_vectorz<PGVector.amax_marginal_relevance_search_with_score_by_vector~  s    < !!###++- 	N 	N 449 5  G MTT&f33==TNT5"**5'	L 99'BJ"+J"7M$!Q1;LAM!	N 	N 	N 	$	N U N!	N 	N 	N 	Ns   DC+DC-DC>C/C>C12AC>C6C6C>D%C<&D-D/C>1C><D>DDDDc                h    | j                   j                  |      } | j                  |f||||d|S )v  Return docs selected using the maximal marginal relevance.

        Maximal marginal relevance optimizes for similarity to query AND diversity
            among selected documents.

        Args:
            query (str): Text to look up documents similar to.
            k (int): Number of Documents to return. Defaults to 4.
            fetch_k (int): Number of Documents to fetch to pass to MMR algorithm.
                Defaults to 20.
            lambda_mult (float): Number between 0 and 1 that determines the degree
                of diversity among the results with 0 corresponding
                to maximum diversity and 1 to minimum diversity.
                Defaults to 0.5.
            filter (Optional[Dict[str, str]]): Filter by metadata. Defaults to None.

        Returns:
            List[Document]: List of Documents selected by maximal marginal relevance.
        r+  r  r  r[   )r}   r,  'max_marginal_relevance_search_by_vectorr   rZ   r+  r  r  r[   r   r   s           r:   max_marginal_relevance_searchz&PGVector.max_marginal_relevance_search  sK    8 OO//6	;t;;
#
 
 	
r9   c                   K   | j                          d{    | j                  j                  |       d{   } | j                  |f||||d| d{   S 7 G7 &7 w)r  Nr  )r   r}   r1  (amax_marginal_relevance_search_by_vectorr  s           r:   amax_marginal_relevance_searchz'PGVector.amax_marginal_relevance_search  sx     8 !!###//66u==	BTBB
#
 
 
 	
 	$=
s1   A$A"A$A A$A"A$ A$"A$c           	     l    | j                   j                  |      } | j                  d|||||d|}|S )  Return docs selected using the maximal marginal relevance with score.

        Maximal marginal relevance optimizes for similarity to query AND diversity
            among selected documents.

        Args:
            query (str): Text to look up documents similar to.
            k (int): Number of Documents to return. Defaults to 4.
            fetch_k (int): Number of Documents to fetch to pass to MMR algorithm.
                Defaults to 20.
            lambda_mult (float): Number between 0 and 1 that determines the degree
                of diversity among the results with 0 corresponding
                to maximum diversity and 1 to minimum diversity.
                Defaults to 0.5.
            filter (Optional[Dict[str, str]]): Filter by metadata. Defaults to None.

        Returns:
            List[Tuple[Document, float]]: List of Documents selected by maximal marginal
                relevance to the query and score for each.
        r   r+  r  r  r[   r8   )r}   r,  r  	r   rZ   r+  r  r  r[   r   r   r8  s	            r:   (max_marginal_relevance_search_with_scorez1PGVector.max_marginal_relevance_search_with_score  sO    : OO//6	FtFF 
#
 
 r9   c           	        K   | j                          d{    | j                  j                  |       d{   } | j                  d|||||d| d{   }|S 7 I7 (7 
w)r  Nr  r8   )r   r}   r1  r  r  s	            r:   )amax_marginal_relevance_search_with_scorez2PGVector.amax_marginal_relevance_search_with_score$  s|     : !!###//66u==	MTMM 
#
 
 
  	$=
s1   A&A "A&A"A&A$A&"A&$A&c                H     | j                   |f||||d|}t        |      S )  Return docs selected using the maximal marginal relevance
            to embedding vector.

        Maximal marginal relevance optimizes for similarity to query AND diversity
            among selected documents.

        Args:
            embedding (str): Text to look up documents similar to.
            k (int): Number of Documents to return. Defaults to 4.
            fetch_k (int): Number of Documents to fetch to pass to MMR algorithm.
                Defaults to 20.
            lambda_mult (float): Number between 0 and 1 that determines the degree
                of diversity among the results with 0 corresponding
                to maximum diversity and 1 to minimum diversity.
                Defaults to 0.5.
            filter (Optional[Dict[str, str]]): Filter by metadata. Defaults to None.

        Returns:
            List[Document]: List of Documents selected by maximal marginal relevance.
        r  )r  r   r   r   r+  r  r  r[   r   r   s           r:   r  z0PGVector.max_marginal_relevance_search_by_vectorM  sB    : R$QQ
#
 
  00r9   c                   K   | j                          d{     | j                  |f||||d| d{   }t        |      S 7 /7 w)r
  Nr  )r   r  r   r  s           r:   r   z1PGVector.amax_marginal_relevance_search_by_vectoru  sj     : !!###J$JJ'   	  00 	$s   A
AA
AA
A
c              #     K   | j                   rt        d      | j                         5 }t        t        |       ddd       y# 1 sw Y   yxY ww)Make an async session.zsAttempting to use a sync method in when async mode is turned on. Please use the corresponding async method instead.N)r   r   r   r\   r%   r   s     r:   r   zPGVector._make_sync_session  sS      ??E  ! 	0Wgw//	0 	0 	0s   (AA	AAAc                  K   | j                   st        d      | j                         4 d{   }t        t        |       ddd      d{    y7 (7 # 1 d{  7  sw Y   yxY ww)r  ztAttempting to use an async method in when sync mode is turned on. Please use the corresponding async method instead.N)r   r   r   r\   r"   r   s     r:   r   zPGVector._make_async_session  sn      E  %%' 	5 	57lG44	5 	5 	5 	5 	5 	5 	5sD   ,A0AA0AA0AA0A0A-!A$"A-)A0c          	     D   g }| j                         5 }| j                  |      }| j                  j                  |j                  k(  g} t        | j                        j                  | j                  j                  j                  |            j                  | }|j                  |      j                         j                         D ]=  }|j                  t        |j                  |j                  |j                                ? 	 ddd       |S # 1 sw Y   |S xY w)Get documents by ids.rM  N)r   r   rT   r   rz   r   rf   r   r   r[   re   rg   r  r  r   r   rl   )r   r   r  rb   rU   r  r   rP  s           r:   
get_by_idszPGVector.get_by_ids  s   	$$& 	',,W5J,,::jooMNI'' t**--11#67	$  "//$/779==?   !99%+__!'!1!1	& '	& s   C7DDc          	       K   g }| j                         4 d{   }| j                  |       d{   }| j                  j                  |j                  k(  g} t        | j                        j                  | j                  j                  j                  |            j                  | }|j                  |       d{   j                         j                         }|D ]F  }|j                  t        t        |j                        |j                   |j"                               H ddd      d{    |S 7 (7 7 7 # 1 d{  7  sw Y   |S xY ww)r  NrM  )r   r   rT   r   rz   r   rf   r   r   r[   re   rg   r  r  r   rt   r   rl   )	r   r   r  rb   rU   r  r   rH  rP  s	            r:   aget_by_idszPGVector.aget_by_ids  sA    	++- 	 	#33G<<J,,::jooMNI'' t**--11#67	$  -4OOD,A&A%J%J%L%P%P%RG!   vyy>%+__!'!1!1	 	, -	< 'B	 	 	 	, sh   E!EE!EEBEEA+E/E!:E	;E!EE	E!EEEE!)r}   r   r   z3Union[None, DBConnection, Engine, AsyncEngine, str]r   Optional[int]r   rt   r   rw   r   r-   r   rd  r   zOptional[logging.Logger]r   z"Optional[Callable[[float], float]]r   zOptional[dict[str, Any]]r   rd  r   rd  r   rd  ru   None)ru   r  )ru   r   )rb   r%   ru   r  )rb   r"   ru   r  )NF)r   Optional[List[str]]r   rd  r   r   ru   r  )rb   r%   ru   r   )rb   r"   ru   r   )r  	List[str]r}   List[List[float]]r   r   r  Optional[List[dict]]r   r  r   rt   r   r-   r   zOptional[str]r   rd  r   rd  r   r   ru   r   )NN)r  Sequence[str]r}   r  r  r  r   r  r   r   ru   r  )
r  zIterable[str]r  r  r   r  r   r   ru   r  )   N)
rZ   rt   r+  rb  r[   rw   r   r   ru   List[Document])rZ   rt   r+  rb  r[   rw   ru   List[Tuple[Document, float]])ru   r   )r   List[float]r+  rb  r[   rw   ru   r  )rH  r   ru   r  )ri  rt   rC  r   ru   r   )r[   r   ru   zList[SQLColumnExpression])r  r   ru   r   )r   r  r+  rb  r[   Optional[Dict[str, str]]ru   Sequence[Any])
rb   r"   r   r  r+  rb  r[   r   ru   r!  )
r   r  r+  rb  r[   rw   r   r   ru   r  rY   )ra   Type[PGVector]r  r  r   r   r  r  r   rt   r   r-   r   r  r   rd  r   rd  r   r   ru   r   )r  zList[Tuple[str, List[float]]]r   r   r  r  r   rt   r   r-   r   r  r   rd  r   r   ru   r   )ra   r"  r   r   r   rt   r   r-   r   rd  r   Optional[DBConnection]r   r   ru   r   )r   zDict[str, Any]ru   rt   )ra   r"  r  r  r   r   r   r#  r   rt   r   r-   r   r  r   rd  r   rd  r   r   ru   r   )ra   r"  r  r  r   r   r   rt   r   r-   r   r  r   rd  r   rd  r   r   ru   r   )r  rt   r  rt   r  rb  r  rt   r  rt   r  rt   ru   rt   )ru   zCallable[[float], float])r     g      ?N)r   r  r+  rb  r  rb  r  rc  r[   r   r   r   ru   r  )rZ   rt   r+  rb  r  rb  r  rc  r[   r   r   r   ru   r  )rZ   rt   r+  rb  r  rb  r  rc  r[   rw   r   r   ru   r  )r   r  r+  rb  r  rb  r  rc  r[   r   r   r   ru   r  )ru   zGenerator[Session, None, None])ru   z"AsyncGenerator[AsyncSession, None])r   r  ru   r  )Lr1   r2   r3   r4   "_LANGCHAIN_DEFAULT_COLLECTION_NAMEDEFAULT_DISTANCE_STRATEGYr   r   r   propertyr}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r~   r  r  r  r  r$  r'  r/  r3  r9  r<  r   r6  r;  rG  rt  r  r  r  rF  rK  r-  r2  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   
contextlibcontextmanagerr   asynccontextmanagerr   r  r  r8   r9   r:   r   r      sW   z@ KO*.A.2.G&++/AE04!% Y!Y! H	Y!
 (Y! Y! ,Y! ,Y!  $Y! )Y! ?Y! .Y! Y! Y! Y!  
!Y!v!	!(	(& ' 'N:
:

8##)# $( %! ! ! 	!
 
!J $( %"# "# "# 	"#
 
"#HOV
  +/#'A.G$(&+# ## &# 	#
 (# !# # ,# "#  $# # # 
# #J  +/#'A.G$(&+$ $$ &$ 	$
 ($ !$ $ ,$ "$  $$ $ $ 
$ $T +/#'88 &8 (	8
 !8 8 
8| +/#'99 &9 (	9
 !9 9 
9| +/#'	

 (
 !	

 
 

B +/#'	

 (
 !	

 
 

B !%	

 
 	

 
 

8 !%	

 
 	

 
 

8 !%	  	
 
&4 !%	  	
 
&.    !%		9	9 	9 		9
 
&	9 !%	== = 	=
 
&=t(t( t( 
	t(lB"H	"2k` +/	(( ( )	(
 
(\ +/** * 	*
 )* 
*^ !%	11 1 	1
 1 
14 !%	11 1 	1
 1 
10 
 +/	
  B.G#'&+


 
 (	
 
 ,
 !
  $
 
 
 

 
: 
 +/A.G#'&+
 


 
 (	

 
 ,
 !
  $
 
 
 

 
8  +/A.G#'&+6
66
 6

 (6
 6
 ,6
 !6
  $6
 6
 
6
 6
p 
 +/A.G#'&+*
6*
 *
 (	*

 *
 ,*
 !*
  $*
 *
 
*
 *
X 
  B.G&+-1 	
 ,  $ +  
 4 
  B.G&+-1 	
 ,  $ +  
 6 ! !   .2A.G#'&+

!
 

 +
 
 ,
 !
  $
 
 
 

 
> 
  B.G#'&+#
 #
#
!#
 #
 	#

 ,#
 !#
  $#
 #
 #
 
#
 #
J SS S 	S
 S S S 
S S<  +/,J,J ,J 	,J
 ,J ),J ,J 
&,Jb  +//N/N /N 	/N
 /N )/N /N 
&/Nh  +/$
$
 $
 	$

 $
 )$
 $
 
$
R  +/%
%
 %
 	%

 %
 )%
 %
 
%
T  !%&& & 	&
 & & & 
&&V  !%'' ' 	'
 ' ' ' 
&'X  +/&1&1 &1 	&1
 &1 )&1 &1 
&1V  +/)1)1 )1 	)1
 )1 ))1 )1 
)1V 0 0 ##5 $50r9   r   rY   )r   r  ru   r   )r   r   ru   r  )r   r   ru   r  )T
__future__r   r(  enumr   rz   warningstypingr   r   r   r   r   r	   r
   r   r   r   r   r   r   r\   numpyr  r]   langchain_core.documentsr   langchain_core.embeddingsr   langchain_core.utilsr   langchain_core.vectorstoresr   r   r   r   r   r   sqlalchemy.dialects.postgresqlr   r   r   r   r   sqlalchemy.enginer   r    sqlalchemy.ext.asyncior!   r"   r#   r$   sqlalchemy.ormr%   r&   r'   r(   r)   langchain_postgres._utilsr*   simplefilterPendingDeprecationWarningrt   Enumr-   r6   r&  r   r%  r<   r   r_  SPECIAL_CASED_OPERATORSTEXT_OPERATORSLOGICAL_OPERATORSsetunionr^  r   r   r   engineDBConnectionr   r8   r9   r:   <module>rC     sc   "           - 0 5 3 U U N N 0   A   f7 8 sDII   -33  &1 " #     
 ,  
U>
U
U"#	 }@/
 Z&&--s23n{ nr9   