
    Ng?C                        d dl m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 d dlmZ d dlmZ d dlmZ erd dlZ G d de          ZdS )	    )annotationsN)
TYPE_CHECKINGAnyCallableDictIterableListOptionalTupleTypeUnion)Document)
Embeddings)VectorStorec                      e Zd ZdZ	 	 	 dCdDdZedEd            Z	 dFdGdZ	 dHdIdZ	 dHdJd!Z		 dHdKd%Z
	 dHdLd'ZdMd+ZdNd,Z	 dHdOd-Z	 dHdPd/Ze	 dFdQd5            Ze	 	 	 	 	 	 	 	 	 	 dRdSd?            ZdTdAZdUdBZdS )VMarqoa  `Marqo` vector store.

    Marqo indexes have their own models associated with them to generate your
    embeddings. This means that you can selected from a range of different models
    and also use CLIP models to create multimodal indexes
    with images and text together.

    Marqo also supports more advanced queries with multiple weighted terms, see See
    https://docs.marqo.ai/latest/#searching-using-weights-in-queries.
    This class can flexibly take strings or dictionaries for weighted queries
    in its similarity search methods.

    To use, you should have the `marqo` python package installed, you can do this with
    `pip install marqo`.

    Example:
        .. code-block:: python

            import marqo
            from langchain_community.vectorstores import Marqo
            client = marqo.Client(url=os.environ["MARQO_URL"], ...)
            vectorstore = Marqo(client, index_name)

    Nclientmarqo.Client
index_namestradd_documents_settingsOptional[Dict[str, Any]]searchable_attributesOptional[List[str]]page_content_builder)Optional[Callable[[Dict[str, Any]], str]]c                    	 ddl }n# t          $ r t          d          w xY wt          ||j                  st	          dt          |                     || _        || _        |i n|| _        || _	        || _
        dg| _        d| _        dS )zInitialize with Marqo client.r   NRCould not import marqo python package. Please install it with `pip install marqo`.z2client should be an instance of marqo.Client, got texti   )marqoImportError
isinstanceClient
ValueErrortype_client_index_name_add_documents_settings_searchable_attributesr   tensor_fields_document_batch_size)selfr   r   r   r   r   r    s          b/var/www/html/ai-engine/env/lib/python3.11/site-packages/langchain_community/vectorstores/marqo.py__init__zMarqo.__init__4   s    	LLLL 	 	 	>  	
 &%,// 	ST&\\SS   %(0BB6L 	$ '<#$8!$X$(!!!s    !returnOptional[Embeddings]c                    d S N r,   s    r-   
embeddingszMarqo.embeddingsT   s    t    textsIterable[str]	metadatasOptional[List[dict]]kwargsr   	List[str]c                   | j                             | j                                                  }d|v r|d         d         s|                    d          rt          d          g }d}t          |          D ]R\  }}||rt          j        ||                   nt          j        i           d}	|	                    |	           |dz  }Sg }
t          d|| j                  D ]} | j                             | j                  j        |||| j        z            fd| j        i| j        }|d         r d	| d
|| j        z    d}t          |          |
d |d         D             z  }
|
S )a  Upload texts with metadata (properties) to Marqo.

        You can either have marqo generate ids for each document or you can provide
        your own by including a "_id" field in the metadata objects.

        Args:
            texts (Iterable[str]): am iterator of texts - assumed to preserve an
            order that matches the metadatas.
            metadatas (Optional[List[dict]], optional): a list of metadatas.

        Raises:
            ValueError: if metadatas is provided and the number of metadatas differs
            from the number of texts.

        Returns:
            List[str]: The list of ids that were added.
        index_defaults!treat_urls_and_pointers_as_imageszMarqo.add_texts is disabled for multimodal indexes. To add documents with a multimodal index use the Python client for Marqo directly.r   )r   metadata   r*   errorsz.Error in upload for documents in index range [,z], check Marqo logs.c                    g | ]
}|d          S )_idr3   ).0items     r-   
<listcomp>z#Marqo.add_texts.<locals>.<listcomp>   s    >>>DDK>>>r6   items)r&   indexr'   get_settingsgetr$   	enumeratejsondumpsappendranger+   add_documentsr*   r(   RuntimeError)r,   r7   r9   r;   settings	documentsnum_docsir   docidsresponseerr_msgs                r-   	add_textszMarqo.add_textsX   s   0 <%%d&677DDFF(()*+NO )||?@@ ) T   +-	 '' 	 	GAt8AUDJy|444tzRT~~ C S!!!MHHq(D$=>> 	? 	?AIt|))$*:;;I!a$";;;< "0 . H
 ! ,)Q ) )444) ) ) 
 #7+++>>HW,=>>>>CC
r6      queryUnion[str, Dict[str, float]]kintList[Document]c                ^    |                      ||          }|                     |          }|S )a{  Search the marqo index for the most similar documents.

        Args:
            query (Union[str, Dict[str, float]]): The query for the search, either
            as a string or a weighted query.
            k (int, optional): The number of documents to return. Defaults to 4.

        Returns:
            List[Document]: k documents ordered from best to worst match.
        r^   r`   )marqo_similarity_search/_construct_documents_from_results_without_score)r,   r^   r`   r;   resultsrU   s         r-   similarity_searchzMarqo.similarity_search   s5      ..Ua.@@HHQQ	r6   List[Tuple[Document, float]]c                ^    |                      ||          }|                     |          }|S )a  Return documents from Marqo that are similar to the query as well
        as their scores.

        Args:
            query (str): The query to search with, either as a string or a weighted
            query.
            k (int, optional): The number of documents to return. Defaults to 4.

        Returns:
            List[Tuple[Document, float]]: The matching documents and their scores,
            ordered by descending score.
        rd   )re   ,_construct_documents_from_results_with_score)r,   r^   r`   rg   scored_documentss        r-   similarity_search_with_scorez"Marqo.similarity_search_with_score   s6    " ..Ua.@@LLWUUr6   queries&Iterable[Union[str, Dict[str, float]]]List[List[Document]]c                    |                      ||          }g }|d         D ],}|                     |          }|                    |           -|S )a  Search the marqo index for the most similar documents in bulk with multiple
        queries.

        Args:
            queries (Iterable[Union[str, Dict[str, float]]]): An iterable of queries to
            execute in bulk, queries in the list can be strings or dictionaries of
            weighted queries.
            k (int, optional): The number of documents to return for each query.
            Defaults to 4.

        Returns:
            List[List[Document]]: A list of results for each query.
        rn   r`   result)marqo_bulk_similarity_searchrf   rP   r,   rn   r`   r;   bulk_resultsbulk_documentsrg   rU   s           r-   bulk_similarity_searchzMarqo.bulk_similarity_search   se    & 88A8NN/1#H- 	- 	-GLLWUUI!!),,,,r6   "List[List[Tuple[Document, float]]]c                    |                      ||          }g }|d         D ],}|                     |          }|                    |           -|S )a5  Return documents from Marqo that are similar to the query as well as
        their scores using a batch of queries.

        Args:
            query (Iterable[Union[str, Dict[str, float]]]): An iterable of queries
            to execute in bulk, queries in the list can be strings or dictionaries
            of weighted queries.
            k (int, optional): The number of documents to return. Defaults to 4.

        Returns:
            List[Tuple[Document, float]]: A list of lists of the matching
            documents and their scores for each query
        rr   rs   )rt   rk   rP   ru   s           r-   !bulk_similarity_search_with_scorez'Marqo.bulk_similarity_search_with_score   se    & 88A8NN=?#H- 	- 	-GII'RRI!!),,,,r6   rg   Dict[str, List[Dict[str, str]]]List[Tuple[Document, Any]]c                   g }|d         D ]{}| j         	|d         }n|                      |          }t          j        |                    dd                    }|                    t          ||          |d         f           ||S )  Helper to convert Marqo results into documents.

        Args:
            results (List[dict]): A marqo results object with the 'hits'.
            include_scores (bool, optional): Include scores alongside documents.
            Defaults to False.

        Returns:
            Union[List[Document], List[Tuple[Document, float]]]: The documents or
            document score pairs if `include_scores` is true.
        hitsNr   r@   {}page_contentr@   _scorer   rN   loadsrL   rP   r   r,   rg   rU   resr   r@   s         r-   rk   z2Marqo._construct_documents_from_results_with_score   s     13	6? 		 		C(06{0055z#''*d";";<<Hth???XO    r6   c                   g }|d         D ]s}| j         	|d         }n|                      |          }t          j        |                    dd                    }|                    t          ||                     t|S )r   r   Nr   r@   r   r   r   r   s         r-   rf   z5Marqo._construct_documents_from_results_without_score  s     %'	6? 	M 	MC(06{0055z#''*d";";<<HX4(KKKLLLLr6   c                z    | j                             | j                                      || j        |          }|S )a"  Return documents from Marqo exposing Marqo's output directly

        Args:
            query (str): The query to search with.
            k (int, optional): The number of documents to return. Defaults to 4.

        Returns:
            List[Dict[str, Any]]: This hits from marqo.
        qr   limitr&   rJ   r'   searchr)   )r,   r^   r`   rg   s       r-   re   zMarqo.marqo_similarity_search-  sB     ,$$T%566==4+Fa > 
 
 r6   0Dict[str, List[Dict[str, List[Dict[str, str]]]]]c                ,     d fd|D             i}|S )a  Return documents from Marqo using a bulk search, exposes Marqo's
        output directly

        Args:
            queries (Iterable[Union[str, Dict[str, float]]]): A list of queries.
            k (int, optional): The number of documents to return for each query.
            Defaults to 4.

        Returns:
            Dict[str, Dict[List[Dict[str, Dict[str, Any]]]]]: A bulk search results
            object
        rs   c                    g | ]<}j                             j                                      |j                   =S )r   r   )rF   r^   r`   r,   s     r-   rH   z6Marqo.marqo_bulk_similarity_search.<locals>.<listcomp>P  s^         ""4#344;;43NVW <    r6   r3   )r,   rn   r`   rv   s   ` ` r-   rt   z"Marqo.marqo_bulk_similarity_search@  sE            %	  
 r6   clsType[Marqo]rU   	embeddingUnion[Embeddings, None]c                R    d |D             }d |D             } | j         |fd|i|S )a  Return VectorStore initialized from documents. Note that Marqo does not
        need embeddings, we retain the parameter to adhere to the Liskov substitution
        principle.


        Args:
            documents (List[Document]): Input documents
            embedding (Any, optional): Embeddings (not required). Defaults to None.

        Returns:
            VectorStore: A Marqo vectorstore
        c                    g | ]	}|j         
S r3   )r   rF   ds     r-   rH   z(Marqo.from_documents.<locals>.<listcomp>m  s    333A333r6   c                    g | ]	}|j         
S r3   )r@   r   s     r-   rH   z(Marqo.from_documents.<locals>.<listcomp>n  s    333AQZ333r6   r9   )
from_texts)r   rU   r   r;   r7   r9   s         r-   from_documentszMarqo.from_documentsZ  sI    & 4333333333	s~eCCyCFCCCr6    http://localhost:8882Turlapi_key)Optional[Callable[[Dict[str, str]], str]]index_settingsverboseboolc                   	 ddl }n# t          $ r t          d          w xY w|s t          t          j                              } |j        ||          }	 |                    ||
pi            |rt          d| d           n%# t          $ r |rt          d| d	           Y nw xY w | ||||pi |	
          }|	                    ||           |S )a  Return Marqo initialized from texts. Note that Marqo does not need
        embeddings, we retain the parameter to adhere to the Liskov
        substitution principle.

        This is a quick way to get started with marqo - simply provide your texts and
        metadatas and this will create an instance of the data store and index the
        provided data.

        To know the ids of your documents with this approach you will need to include
        them in under the key "_id" in your metadatas for each text

        Example:
        .. code-block:: python

                from langchain_community.vectorstores import Marqo

                datastore = Marqo(texts=['text'], index_name='my-first-index',
                url='http://localhost:8882')

        Args:
            texts (List[str]): A list of texts to index into marqo upon creation.
            embedding (Any, optional): Embeddings (not required). Defaults to None.
            index_name (str, optional): The name of the index to use, if none is
            provided then one will be created with a UUID. Defaults to None.
            url (str, optional): The URL for Marqo. Defaults to "http://localhost:8882".
            api_key (str, optional): The API key for Marqo. Defaults to "".
            metadatas (Optional[List[dict]], optional): A list of metadatas, to
            accompany the texts. Defaults to None.
            this is only used when a new index is being created. Defaults to "cpu". Can
            be "cpu" or "cuda".
            add_documents_settings (Optional[Dict[str, Any]], optional): Settings
            for adding documents, see
            https://docs.marqo.ai/0.0.16/API-Reference/documents/#query-parameters.
            Defaults to {}.
            index_settings (Optional[Dict[str, Any]], optional): Index settings if
            the index doesn't exist, see
            https://docs.marqo.ai/0.0.16/API-Reference/indexes/#index-defaults-object.
            Defaults to {}.

        Returns:
            Marqo: An instance of the Marqo vector store
        r   Nr   )r   r   )settings_dictzCreated z successfully.zIndex z exists.)r   r   r   )
r    r!   r   uuiduuid4r#   create_indexprint	Exceptionr\   )r   r7   r   r9   r   r   r   r   r   r   r   r   r;   r    r   instances                   r-   r   zMarqo.from_textsq  sF   t	LLLL 	 	 	>  	  	+TZ\\**J#w777	5
.:NBOOO =;;;;<<< 	5 	5 	5 53z333444	5 #"7#9#?R!5
 
 
 	5),,,s    !.B B*)B*List[Dict[str, str]]c                @    | j                                         d         S )zHelper to see your available indexes in marqo, useful if the
        from_texts method was used without an index name specified

        Returns:
            List[Dict[str, str]]: The list of indexes
        rg   )r&   get_indexesr4   s    r-   r   zMarqo.get_indexes  s     |'')))44r6   c                p    | j                             | j                                                  d         S )zvHelper to see the number of documents in the index

        Returns:
            int: The number of documents
        numberOfDocuments)r&   rJ   r'   	get_statsr4   s    r-   get_number_of_documentszMarqo.get_number_of_documents  s/     |!!$"233==??@STTr6   )NNN)
r   r   r   r   r   r   r   r   r   r   )r/   r0   r2   )r7   r8   r9   r:   r;   r   r/   r<   )r]   )r^   r_   r`   ra   r;   r   r/   rb   )r^   r_   r`   ra   r/   ri   )rn   ro   r`   ra   r;   r   r/   rp   )rn   ro   r`   ra   r;   r   r/   ry   )rg   r|   r/   r}   )rg   r|   r/   rb   )r^   r_   r`   ra   r/   r|   )rn   ro   r`   ra   r/   r   )
r   r   rU   rb   r   r   r;   r   r/   r   )
NNr   r   r   NNNNT)r7   r<   r   r   r9   r:   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r;   r   r/   r   )r/   r   )r/   ra   )__name__
__module____qualname____doc__r.   propertyr5   r\   rh   rm   rx   r{   rk   rf   re   rt   classmethodr   r   r   r   r3   r6   r-   r   r      s	        : <@59JN) ) ) ) )@    X +/> > > > >F     0          2     <     6   6   8     ( IJ    4  .2D D D D [D,  *.*;?59JN37V V V V [Vp5 5 5 5U U U U U Ur6   r   )
__future__r   rN   r   typingr   r   r   r   r   r	   r
   r   r   r   langchain_core.documentsr   langchain_core.embeddingsr   langchain_core.vectorstoresr   r    r   r3   r6   r-   <module>r      s2   " " " " " "                          . - - - - - 0 0 0 0 0 0 3 3 3 3 3 3 LLLU U U U UK U U U U Ur6   