
    Q
ih@                        d dl 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 d dlmZ dZ G d d          Z	 	 	 	 	 	 	 	 	 d dededededee         deed                  dee         dee         dee         dee         dee         deeeef                  fdZ	 	 	 	 d!ded         dee         dee         dee         dee         f
dZd
S )"    )AnyDictListLiteralOptionalSetUnion)Filter)FilterExpression)array_to_buffer)FullTextQueryHelperz9Hybrid queries require Redis >= 8.4.0 and redis-py>=7.1.0c            2          e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d%dededeeee         f         dededede	e         de	e
d                  dede	e         dede	e         de	eeef                  de	e
d                  dededede	e         ded e	e         d!e	ee                  d"e	eeee         f                  d#e	eeef                  f.d$ZdS )&HybridQuerya  
    A hybrid search query that combines text search and vector similarity, with configurable fusion methods.

    .. code-block:: python

        from redisvl.query import HybridQuery
        from redisvl.index import SearchIndex

        index = SearchIndex.from_yaml("path/to/index.yaml")

        query = HybridQuery(
            text="example text",
            text_field_name="text_field",
            vector=[0.1, 0.2, 0.3],
            vector_field_name="vector_field",
            text_scorer="BM25STD",
            yield_text_score_as="text_score",
            yield_vsim_score_as="vector_similarity",
            combination_method="LINEAR",
            linear_alpha=0.3,
            yield_combined_score_as="hybrid_score",
            num_results=10,
            return_fields=["field1", "field2"],
            stopwords="english",
        )

        results = index.query(query)

    See Also:
        - `FT.HYBRID command documentation <https://redis.io/docs/latest/commands/ft.hybrid>`_
        - `redis-py hybrid_search documentation <https://redis.readthedocs.io/en/stable/redismodules.html#redis.commands.search.commands.SearchCommands.hybrid_search>`_
    vectorBM25STDN
   {Gz?   <   333333?float32englishtexttext_field_namevector_field_namevector_param_nametext_scoreryield_text_score_asvector_search_methodKNNRANGEknn_ef_runtimerange_radiusrange_epsilonyield_vsim_score_asfilter_expressioncombination_methodRRFLINEAR
rrf_windowrrf_constantlinear_alphayield_combined_score_asdtypenum_resultsreturn_fields	stopwordstext_weightsc                 J   	 ddl m}m} n)# t          t          f$ r t          t
                    w xY w |            | _        |r| j                            d|           |r | j        j        d |D               t          ||          | _
        | j
                            |||          }t          |t                    r|}nt          ||          }||i| _        t!          ||||||||	|
|||          | _        |rt%          |||||          | _        dS d| _        dS )	a>  
        Instantiates a HybridQuery object.

        Args:
            text: The text to search for.
            text_field_name: The text field name to search in.
            vector: The vector to perform vector similarity search.
            vector_field_name: The vector field name to search in.
            vector_param_name: The name of the parameter substitution containing the vector blob.
            text_scorer: The text scorer to use. Options are {TFIDF, TFIDF.DOCNORM,
                BM25STD, BM25STD.NORM, BM25STD.TANH, DISMAX, DOCSCORE, HAMMING}. Defaults to "BM25STD". For more
                information about supported scoring algorithms,
                see https://redis.io/docs/latest/develop/ai/search-and-query/advanced-concepts/scoring/
            yield_text_score_as: The name of the field to yield the text score as.
            vector_search_method: The vector search method to use. Options are {KNN, RANGE}. Defaults to None.
            knn_ef_runtime: The exploration factor parameter for HNSW, optional if `vector_search_method` is "KNN".
            range_radius: The search radius to use, required if `vector_search_method` is "RANGE".
            range_epsilon: The epsilon value to use, optional if `vector_search_method` is "RANGE"; defines the
                accuracy of the search.
            yield_vsim_score_as: The name of the field to yield the vector similarity score as.
            filter_expression: The filter expression to use for both the text and vector searches. Defaults to None.
            combination_method: The combination method to use. Options are {RRF, LINEAR}. If not specified, the server
                defaults to RRF. If "RRF" is specified, then at least one of `rrf_window` or `rrf_constant` must be
                provided. If "LINEAR" is specified, then at least one of `linear_alpha` or `linear_beta` must be
                provided.
            rrf_window: The window size to use for the reciprocal rank fusion (RRF) combination method. Limits
                fusion scope.
            rrf_constant: The constant to use for the reciprocal rank fusion (RRF) combination method. Controls decay
                of rank influence.
            linear_alpha: The weight of the text query for the linear combination method (LINEAR).
            yield_combined_score_as: The name of the field to yield the combined score as.
            dtype: The data type of the vector. Defaults to "float32".
            num_results: The number of results to return.
            return_fields: The fields to return. Defaults to None.
            stopwords (Optional[Union[str, Set[str]]], optional): The stopwords to remove from the
                provided text prior to search-use. If a string such as "english" "german" is
                provided then a default set of stopwords for that language will be used. if a list,
                set, or tuple of strings is provided then those will be used as stopwords.
                Defaults to "english". if set to "None" then no stopwords will be removed.

                Note: This parameter controls query-time stopword filtering (client-side).
                For index-level stopwords configuration (server-side), see IndexInfo.stopwords.
                Using query-time stopwords with index-level STOPWORDS 0 is counterproductive.
            text_weights (Optional[Dict[str, float]]): The importance weighting of individual words
                within the query text. Defaults to None, as no modifications will be made to the
                text_scorer score.

        Raises:
            ImportError: If redis-py>=7.1.0 is not installed.
            TypeError: If the stopwords are not a set, list, or tuple of strings.
            ValueError: If the text string is empty, or if the text string becomes empty after
                stopwords are removed.
            ValueError: If `vector_search_method` is defined and isn't one of {KNN, RANGE}.
            ValueError: If `vector_search_method` is "KNN" and `knn_k` is not provided.
            ValueError: If `vector_search_method` is "RANGE" and `range_radius` is not provided.
        r   )CombineResultsMethodHybridPostProcessingConfig)offsetnumc              3       K   | ]	}d | V  
dS )@N ).0fs     C:\Users\Dell Inspiron 16\Desktop\tws\AgrotaPowerBi\back-agrota-powerbi\mcp-client-agrota\venv\Lib\site-packages\redisvl/query/hybrid.py	<genexpr>z'HybridQuery.__init__.<locals>.<genexpr>   s(      -M-M!g!gg-M-M-M-M-M-M    )r3   r4   )
text_queryr   r   r   r   r   r1   r#   r$   r%   r&   r'   )r(   r,   r-   r.   yield_score_asN)"redis.commands.search.hybrid_queryr6   r7   ImportErrorModuleNotFoundError_IMPORT_ERROR_MESSAGEpostprocessing_configlimitloadr   
_ft_helperbuild_query_string
isinstancebytesr   paramsbuild_base_queryquerybuild_combination_methodr(   )selfr   r   r   r   r   r   r   r   r#   r$   r%   r&   r'   r(   r,   r-   r.   r/   r0   r1   r2   r3   r4   r6   r7   query_stringvector_datas                               r?   __init__zHybridQuery.__init__.   s   d	5         01 	5 	5 	53444	5 &@%?%A%A" 	H&,,A;,GGG 	O+D&+-M-M}-M-M-MNN-%
 
 

 99/#4
 
 fe$$ 	9 KK)&%88K {
 &#//# 3!5#)%' 3/
 
 

  	+('9)!-!-#:   ### '+D###    &1)r   r   NNr   Nr   NNNr   r   r   Nr   r   Nr   N)__name__
__module____qualname____doc__strr	   rN   r   floatr   r   intr   r   r   rV   r<   rA   r?   r   r      s        N "*$-1BF (,#-1DHAE!15%'-14=371L+ L+L+ L+ eT%[()	L+
 L+ L+ L+ &c]L+ 'w~'>?L+ L+ uoL+ L+ &c]L+ $E#/?*?$@AL+ %W_%=>L+  !L+" #L+$ %L+& "*#'L+( )L+* c]+L+,  S	*-L+. E#s3x-01/L+0 tCJ/01L+ L+ L+ L+ L+ L+rA   r   r   NrB   r   r   r   r   r   r    r1   r#   r$   r%   r&   r'   c                 P   	 ddl m} ddl m}m}m} n)# t
          t          f$ r t          t                    w xY w || ||          }d}i }|dk    r%|j        }|st          d          ||d<   |r||d	<   n?|d
k    r%|j
        }|st          d          ||d<   |	r|	|d<   n|t          d|           t          |t                    rt          |          }|r$|dk    rt          dt          |                    }nd} |d|z   d|z   ||||
          } |||          S )aq  Build a Redis HybridQuery for performing hybrid search.

    Args:
        text_query: The query for the text search.
        vector_param_name: The name of the parameter substitution containing the vector blob.
        vector_field_name: The vector field name to search in.
        text_scorer: The text scorer to use. Options are {TFIDF, TFIDF.DOCNORM,
            BM25STD, BM25STD.NORM, BM25STD.TANH, DISMAX, DOCSCORE, HAMMING}. Defaults to "BM25STD". For more
            information about supported scroring algorithms,
            see https://redis.io/docs/latest/develop/ai/search-and-query/advanced-concepts/scoring/
        yield_text_score_as: The name of the field to yield the text score as.
        vector_search_method: The vector search method to use. Options are {KNN, RANGE}. Defaults to None.
        num_results: The number of nearest neighbors to return, required if `vector_search_method` is "KNN".
        knn_ef_runtime: The exploration factor parameter for HNSW, optional if `vector_search_method` is "KNN".
        range_radius: The search radius to use, required if `vector_search_method` is "RANGE".
        range_epsilon: The epsilon value to use, optional if `vector_search_method` is "RANGE"; defines the
            accuracy of the search.
        yield_vsim_score_as: The name of the field to yield the vector similarity score as.
        filter_expression: The filter expression to use for the vector similarity search. Defaults to None.

    Notes:
        If RRF combination method is used, then at least one of `rrf_window` or `rrf_constant` must be provided.
        If LINEAR combination method is used, then at least one of `linear_alpha` or `linear_beta` must be provided.

    Raises:
        ImportError: If redis-py>=7.1.0 is not installed.
        ValueError: If `vector_search_method` is defined and isn't one of {KNN, RANGE}.
        ValueError: If `vector_search_method` is "KNN" and `knn_k` is not provided.
        ValueError: If `vector_search_method` is "RANGE" and `range_radius` is not provided.

    Returns:
        A Redis HybridQuery object that defines the text and vector searches to be performed.
    r   )r   )HybridSearchQueryHybridVsimQueryVectorSearchMethods)rT   scorerrC   Nr!   z9Must provide `num_results` if vector_search_method is KNNK
EF_RUNTIMEr"   z4Must provide RADIUS if vector_search_method is RANGERADIUSEPSILONzUnknown vector search method: *FILTERr;   $)r   rU   vsim_search_methodvsim_search_method_paramsfilterrC   )search_queryvector_similarity_query)rD   r   r`   ra   rb   rE   rF   rG   r!   
ValueErrorr"   rM   r   r\   r
   )rB   r   r   r   r   r   r1   r#   r$   r%   r&   r'   RedisHybridQueryr`   ra   rb   rn   rk   rl   vsim_filter
vsim_querys                        r?   rP   rP      s   ^1VVVVVV	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	

 ,- 1 1 1/0001 %$*  L 9=02u$$04 	K   *5!#& 	E6D%l3		(	(06 	USTTT.:!(+ 	A3@%i0		)P:NPPQQQ#%566 3 122 .#55Xs+<'='=>> ! 11++-";*  J ! *   s    &9r(   r)   r,   r-   r.   rC   c                 F   	 ddl m}m} n)# t          t          f$ r t          t
                    w xY wi }| dk    r|j        }|r||d<   |r||d<   n/| dk    r|j        }|r||d<   d|z
  |d	<   nt          d
|            |r||d<   |st          d           |dd|i|S )aU  Build a configuration for combining hybrid search scores.

    Args:
        combination_method: The combination method to use. Options are {RRF, LINEAR}.
        rrf_window: The window size to use for the reciprocal rank fusion (RRF) combination method. Limits
            fusion scope.
        rrf_constant: The constant to use for the reciprocal rank fusion (RRF) combination method. Controls decay
            of rank influence.
        linear_alpha: The weight of the first query for the linear combination method (LINEAR).
        yield_score_as: The name of the field to yield the combined score as.

    Raises:
        ImportError: If redis-py>=7.1.0 is not installed.
        ValueError: If `combination_method` is defined and isn't one of {RRF, LINEAR}.
        ValueError: If `combination_method` is "RRF" and neither `rrf_window` nor `rrf_constant` is provided.
        ValueError: If `combination_method` is "LINEAR" and neither `linear_alpha` nor `linear_beta` is provided.

    Returns:
        A CombineResultsMethod object that defines how the text and vector scores should be combined.
    r   )CombinationMethodsr6   r*   WINDOWCONSTANTr+   ALPHA   BETAzUnknown combination method: YIELD_SCORE_ASzTNo parameters provided for combination method - must provide at least one parameter.methodr<   )	rD   ru   r6   rE   rF   rG   r*   r+   rp   )	r(   r,   r-   r.   rC   ru   r6   method_paramsr|   s	            r?   rR   rR   /  sP   61	
 	
 	
 	
 	
 	
 	
 	
 	
 ,- 1 1 1/0001 %'MU""#' 	1&0M(# 	5(4M*%	x	'	'#* 	5%1M'"$%$4M&! L8JLLMMM 9*8&' 
b
 
 	
    
  rW   )	r   NNNNNNNN)NNNN)typingr   r   r   r   r   r   r	   redis.commands.search.queryr
   redisvl.query.filterr   redisvl.redis.utilsr   $redisvl.utils.full_text_query_helperr   rG   r   r\   r^   r]   rP   rR   r<   rA   r?   <module>r      s   A A A A A A A A A A A A A A A A A A . . . . . . 1 1 1 1 1 1 / / / / / / D D D D D DS n+ n+ n+ n+ n+ n+ n+ n+j !)->B!%$($(%))-@Do ooo o 	o
 "#o #7>#:;o #o SMo 5/o E?o "#o  c+;&; <=o o o oh !%$($($(? ?0?? 5/? 5/	?
 SM? ? ? ? ? ?rA   