
    3i$                         S SK JrJr  S SKJrJrJrJrJrJ	r	  S SK
JrJrJrJrJrJrJrJrJrJr  \ " S S5      5       r\ " S S5      5       r\ " S S	5      5       r " S
 S5      rg)    )	dataclassfield)ListDictAnyUnionSetOptional)
KNNFilterLimit
ProjectionScanRankSelectValWhereKeyc                        \ rS rSr% \\S'   Srg)	CountPlan   scan N)__name__
__module____qualname____firstlineno__r   __annotations____static_attributes__r       \/home/james-whalen/.local/lib/python3.13/site-packages/chromadb/execution/expression/plan.pyr   r      s    
Jr    r   c                   b    \ rS rSr% \\S'   \" \S9r\\S'   \" \	S9r
\	\S'   \" \S9r\\S'   Srg)	GetPlan   r   default_factoryfilterlimit
projectionr   N)r   r   r   r   r   r   r   r   r'   r   r(   r   r)   r   r   r    r!   r#   r#      s4    
J62FF2/E5/":>J
>r    r#   c                   V    \ rS rSr% \\S'   \\S'   \" \S9r	\\S'   \" \
S9r\
\S'   Srg)	KNNPlan   r   knnr%   r'   r)   r   N)r   r   r   r   r   r   r   r   r   r'   r   r)   r   r   r    r!   r+   r+      s*    
J	H62FF2":>J
>r    r+   c                   h   \ rS rSrSr    SS\\\\\	\
4   4      S\\\\\	\
4   4      S\\\\\	\
4   \4      S\\\\\	\
4   \\	   \\	   4      4S jjrS	\\	\
4   4S
 jrSS jrS\\\	4   S	S 4S jrS\\\\\	\
4   4      S	S 4S jrS\\\\\	\
4   4      S	S 4S jrSS\S\S	S 4S jjrSrg)Search'   a  Payload for hybrid search operations.

Can be constructed directly or using builder pattern:

Direct construction with expressions:
    Search(
        where=Key("status") == "active",
        rank=Knn(query=[0.1, 0.2]),
        limit=Limit(limit=10),
        select=Select(keys={Key.DOCUMENT})
    )

Direct construction with dicts:
    Search(
        where={"status": "active"},
        rank={"$knn": {"query": [0.1, 0.2]}},
        limit=10,  # Creates Limit(limit=10, offset=0)
        select=["#document", "#score"]
    )

Builder pattern:
    (Search()
        .where(Key("status") == "active")
        .rank(Knn(query=[0.1, 0.2]))
        .limit(10)
        .select(Key.DOCUMENT))

Builder pattern with dicts:
    (Search()
        .where({"status": "active"})
        .rank({"$knn": {"query": [0.1, 0.2]}})
        .limit(10)
        .select(Key.DOCUMENT))

Filter by IDs:
    Search().where(Key.ID.is_in(["id1", "id2", "id3"]))

Combined with metadata filtering:
    Search().where((Key.ID.is_in(["id1", "id2"])) & (Key("status") == "active"))

Empty Search() is valid and will use defaults:
    - where: None (no filtering)
    - rank: None (no ranking - results ordered by default order)
    - limit: No limit
    - select: Empty selection
Nwhererankr(   selectc                    Uc  SU l         On[        U[        5      (       a  Xl         OR[        U[        5      (       a  [        R                  " U5      U l         O![        S[        U5      R                   35      eUc  SU l        On[        U[        5      (       a  X l        OR[        U[        5      (       a  [        R                  " U5      U l        O![        S[        U5      R                   35      eUc  [        5       U l        O[        U[        5      (       a  X0l        O[        U[        5      (       a  [        R                  " USS.5      U l        OR[        U[        5      (       a  [        R                  " U5      U l        O![        S[        U5      R                   35      eUc  [        5       U l        g[        U[        5      (       a  X@l        g[        U[        5      (       a  [        R                  " U5      U l        g[        U[        [         45      (       a'  [        R                  " S[        U5      05      U l        g[        S[        U5      R                   35      e)	aV  Initialize a Search with optional parameters.

Args:
    where: Where expression or dict for filtering results (defaults to None - no filtering)
           Dict will be converted using Where.from_dict()
    rank: Rank expression or dict for scoring (defaults to None - no ranking)
          Dict will be converted using Rank.from_dict()
          Note: Primitive numbers are not accepted - use {"$val": number} for constant ranks
    limit: Limit configuration for pagination (defaults to no limit)
           Can be a Limit object, a dict for Limit.from_dict(), or an int
           When passing an int, it creates Limit(limit=value, offset=0)
    select: Select configuration for keys (defaults to empty selection)
            Can be a Select object, a dict for Select.from_dict(), 
            or a list/set of strings (e.g., ["#document", "#score"])
N1where must be a Where object, dict, or None, got z/rank must be a Rank object, dict, or None, got r   )r(   offsetz6limit must be a Limit object, dict, int, or None, got keysz>select must be a Select object, dict, list, set, or None, got )_where
isinstancer   dict	from_dict	TypeErrortyper   _rankr   r   _limitintr   _selectlistset)selfr1   r2   r(   r3   s        r!   __init__Search.__init__W   s   . =DKu%%Kt$$//%0DKCDKDXDXCYZ 
 <DJd##Jd##-DJA$t*BUBUAVW 
 ='DKu%%Ks##//EQ*GHDKt$$//%0DKHeI]I]H^_ 
 >!8DL''!L%%!++F3DLs,,!++VT&\,BCDLPQUV\Q]QfQfPgh r    returnc                    U R                   b  U R                   R                  5       OSU R                  b  U R                  R                  5       OSU R                  R                  5       U R                  R                  5       S.$ )z9Convert the Search to a dictionary for JSON serializationN)r'   r2   r(   r3   )r8   to_dictr>   r?   rA   )rD   s    r!   rI   Search.to_dict   sd     04{{/Fdkk))+D,0JJ,BDJJ&&([[((*ll**,	
 	
r    c                     [        [        R                  [        R                  [        R                  [        R
                  1S9n[        U R                  U R                  U R                  US9$ )zASelect all predefined keys (document, embedding, metadata, score)r7   r1   r2   r(   r3   )
r   r   DOCUMENT	EMBEDDINGMETADATASCOREr/   r8   r>   r?   )rD   
new_selects     r!   
select_allSearch.select_all   sG    #,,s||SYY!WX
++DJJdkk*
 	
r    r7   c                 z    [        [        U5      S9n[        U R                  U R                  U R
                  US9$ )zSelect specific keys

Args:
    *keys: Variable number of Key objects or string key names

Returns:
    New Search object with updated select configuration
rL   rM   )r   rC   r/   r8   r>   r?   )rD   r7   rR   s      r!   r3   Search.select   s4     T+
++DJJdkk*
 	
r    c                 *   Uc  SnOe[        U[        5      (       a  UnOM[        U[        5      (       a  [        R                  " U5      nO![	        S[        U5      R                   35      e[        X R                  U R                  U R                  S9$ )ab  Set the where clause for filtering

Args:
    where: A Where expression, dict, or None for filtering
           Dicts will be converted using Where.from_dict()

Example:
    search.where((Key("status") == "active") & (Key("score") > 0.5))
    search.where({"status": "active"})
    search.where({"$and": [{"status": "active"}, {"score": {"$gt": 0.5}}]})
Nr5   rM   )r9   r   r:   r;   r<   r=   r   r/   r>   r?   rA   )rD   r1   converted_wheres      r!   r1   Search.where   s     ="Ou%%#Ot$$#ooe4OCDKDXDXCYZ  !

$++dll
 	
r    	rank_exprc                 *   Uc  SnOe[        U[        5      (       a  UnOM[        U[        5      (       a  [        R                  " U5      nO![	        S[        U5      R                   35      e[        U R                  X R                  U R                  S9$ )a  Set the ranking expression

Args:
    rank_expr: A Rank expression, dict, or None for scoring
               Dicts will be converted using Rank.from_dict()
               Note: Primitive numbers are not accepted - use {"$val": number} for constant ranks

Example:
    search.rank(Knn(query=[0.1, 0.2]) * 0.8 + Val(0.5) * 0.2)
    search.rank({"$knn": {"query": [0.1, 0.2]}})
    search.rank({"$sum": [{"$knn": {"query": [0.1, 0.2]}}, {"$val": 0.5}]})
Nz4rank_expr must be a Rank object, dict, or None, got rM   )r9   r   r:   r;   r<   r=   r   r/   r8   r?   rA   )rD   rZ   converted_ranks      r!   r2   Search.rank   s     !N	4((&N	4((!^^I6NFtIG_G_F`a  ++N++dll
 	
r    r6   c                 f    [        X!S9n[        U R                  U R                  X0R                  S9$ )zSet the limit and offset for pagination

Args:
    limit: Maximum number of results to return
    offset: Number of results to skip (default: 0)

Example:
    search.limit(20, offset=10)
)r6   r(   rM   )r   r/   r8   r>   rA   )rD   r(   r6   	new_limits       r!   r(   Search.limit   s.     5	++DJJi
 	
r    )r?   r>   rA   r8   )NNNN)rG   r/   )r   )r   r   r   r   __doc__r
   r   r   r   strr   r   r   r@   r   r   r	   rE   rI   rS   r   r3   r1   r2   r(   r   r   r    r!   r/   r/   '   sX   -b 9=6:=AOSIeT#s(^345I uT4S>123I eT#s(^S89:	I
 vtCH~tCy#c(JKLIV
c3h 


E#s(O 
 

8E%c3h*?$@A 
h 
8
huT4S>-A'BC 
 
:
3 
 
H 
 
r    r/   N)dataclassesr   r   typingr   r   r   r   r	   r
   &chromadb.execution.expression.operatorr   r   r   r   r   r   r   r   r   r   r   r#   r+   r/   r   r    r!   <module>rf      st    ( 8 8      ? ? ? ? ? ?`
 `
r    