
    LKi              
          S SK JrJr  S SKJrJrJrJrJrJ	r	J
r
  S SKJr  S SKrS SK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KJrJrJr  \ " S S	5      5       r \ " S
 S5      5       r!\ " S S\!5      5       r"\ " S S\!5      5       r#\ " S S\!5      5       r$\ " S S\!5      5       r%\ " S S\!5      5       r&\ " S S\!5      5       r'\ " S S\!5      5       r(\ " S S\!5      5       r)\ " S S\!5      5       r*\ " S S\!5      5       r+\ " S  S!\!5      5       r,\ " S" S#\!5      5       r-\ " S$ S%\!5      5       r.\ " S& S'\!5      5       r/ " S( S)5      r0\0" S*5      \0l1        \0" S+5      \0l2        \0" S,5      \0l3        \0" S-5      \0l4        \0" S.5      \0l5        \0r6\ " S/ S05      5       r7\ " S1 S25      5       r8\ " S3 S45      5       r9\ " S5 S65      5       r:\ " S7 S85      5       r;\ " S9 S:\;5      5       r<\ " S; S<\;5      5       r=\ " S= S>\;5      5       r>\ " S? S@\;5      5       r?\ " SA SB\;5      5       r@\ " SC SD\;5      5       rA\ " SE SF\;5      5       rB\ " SG SH\;5      5       rC\ " SI SJ\;5      5       rD\ " SK SL\;5      5       rE\ " SM SN\;5      5       rF\ " SO SP\;5      5       rG\ " SQ SR5      5       rHSS\\	\0\I4      ST\\I   4SU jrJSS\	\\   \K\SV4   4   ST\\	\0\I4      4SW jrLSX\ISY\\I\4   ST\K\\	\0\I4      \M4   4SZ jrN\ " S[ S\5      5       rO\ " S] S^\O5      5       rP\ " S_ S`\O5      5       rQ\ " Sa Sb5      5       rRg)c    )	dataclassfield)OptionalListDictSetAnyUnioncast)LiteralValueN)NDArray)

EmbeddingsIDsInclude	OneOrManySparseVectorTYPE_KEYSPARSE_VECTOR_TYPE_VALUEmaybe_cast_one_to_manynormalize_embeddingsvalidate_embeddings)
CollectionRequestVersionContextSegmentc                   V    \ rS rSr% \\S'   \\S'   \\S'   \\S'   \S\4S j5       r	Sr
g	)
Scan   
collectionknnmetadatarecordreturnc                 f    [        U R                  R                  U R                  R                  S9$ )N)collection_versionlog_position)r   r   versionr%   selfs    h/var/www/html/dynamic-report/venv/lib/python3.13/site-packages/chromadb/execution/expression/operator.pyr&   Scan.version"   s)    $#6655
 	
     N)__name__
__module____qualname____firstlineno__r   __annotations__r   propertyr   r&   __static_attributes__r,   r+   r)   r   r      s2    	LO
. 
 
r+   r   c                   j    \ rS rSrSrS\\\4   4S jr\	S\\\4   SS 4S j5       r
SS jrSS jrS	rg
)Where+   a  Base class for Where expressions (algebraic data type).

Supports logical operators for combining conditions:
    - AND: where1 & where2
    - OR: where1 | where2

Examples:
    # Simple conditions
    where1 = Key("status") == "active"
    where2 = Key("score") > 0.5

    # Combining with AND
    combined_and = where1 & where2

    # Combining with OR
    combined_or = where1 | where2

    # Complex expressions
    complex_where = (Key("status") == "active") & ((Key("score") > 0.5) | (Key("priority") == "high"))
r"   c                     [        S5      e)zCConvert the Where expression to a dictionary for JSON serialization#Subclasses must implement to_dict()NotImplementedErrorr'   s    r)   to_dictWhere.to_dictB       !"GHHr+   datac                 "   [        U [        5      (       d!  [        S[        U 5      R                   35      eU (       d  [        S5      eSU ;   a  [        U S   [        5      (       d$  [        S[        U S   5      R                   35      e[        U S   5      S:X  a  [        S5      e[        U 5      S:  a  [        S5      eU S    Vs/ s H  n[        R                  U5      PM     nn[        U5      S:X  a  US   $ US   nUSS	  H  nX1-  nM	     U$ S
U ;   a  [        U S
   [        5      (       d$  [        S[        U S
   5      R                   35      e[        U S
   5      S:X  a  [        S5      e[        U 5      S:  a  [        S5      eU S
    Vs/ s H  n[        R                  U5      PM     nn[        U5      S:X  a  US   $ US   nUSS	  H  nX1-  nM	     U$ [        U 5      S:w  a  [        S[        U 5       35      e[        [        U R                  5       5      5      u  pE[        U[        5      (       d!  [        S[        U5      R                   35      e[        U[        5      (       Ga  U(       d  [        SU S35      e[        U5      S:w  a  [        SU S35      e[        [        UR                  5       5      5      u  pgUS:X  a  [        U5      U:H  $ US:X  a  [        U5      U:g  $ US:X  a  [        U5      U:  $ US:X  a  [        U5      U:  $ US:X  a  [        U5      U:  $ US:X  a  [        U5      U:*  $ US:X  aP  [        U[        5      (       d!  [        S[        U5      R                   35      e[        U5      R                  U5      $ US:X  aP  [        U[        5      (       d!  [        S[        U5      R                   35      e[        U5      R!                  U5      $ US:X  a`  [        U[        ["        [$        [&        45      (       d!  [        S[        U5      R                   35      e[        U5      R)                  U5      $ US:X  a`  [        U[        ["        [$        [&        45      (       d!  [        S [        U5      R                   35      e[        U5      R+                  U5      $ US!:X  aP  [        U[        5      (       d!  [        S"[        U5      R                   35      e[        U5      R-                  U5      $ US#:X  aP  [        U[        5      (       d!  [        S$[        U5      R                   35      e[        U5      R/                  U5      $ [        S%U 35      e[        U5      U:H  $ s  snf s  snf )&a  Create Where expression from dictionary.

Supports MongoDB-style query operators:
- {"field": "value"} -> Key("field") == "value" (shorthand for equality)
- {"field": {"$eq": value}} -> Key("field") == value
- {"field": {"$ne": value}} -> Key("field") != value
- {"field": {"$gt": value}} -> Key("field") > value
- {"field": {"$gte": value}} -> Key("field") >= value
- {"field": {"$lt": value}} -> Key("field") < value
- {"field": {"$lte": value}} -> Key("field") <= value
- {"field": {"$in": [values]}} -> Key("field").is_in([values])
- {"field": {"$nin": [values]}} -> Key("field").not_in([values])
- {"field": {"$contains": "text"}} -> Key("field").contains("text")
- {"field": {"$not_contains": "text"}} -> Key("field").not_contains("text")
- {"field": {"$regex": "pattern"}} -> Key("field").regex("pattern")
- {"field": {"$not_regex": "pattern"}} -> Key("field").not_regex("pattern")
- {"$and": [conditions]} -> condition1 & condition2 & ...
- {"$or": [conditions]} -> condition1 | condition2 | ...
zExpected dict for Where, got zWhere dict cannot be empty$andz$and must be a list, got r   z$$and requires at least one condition   z:$and cannot be combined with other fields in the same dictN$orz$or must be a list, got z#$or requires at least one conditionz9$or cannot be combined with other fields in the same dictz/Where dict must contain exactly one field, got z!Field name must be a string, got zOperator dict for field 'z' cannot be emptyz#' must contain exactly one operator$eq$ne$gt$gte$lt$lte$inz$in requires a list, got $ninz$nin requires a list, got 	$containsz3$contains requires a str, int, float, or bool, got $not_containsz7$not_contains requires a str, int, float, or bool, got $regexz&$regex requires a string pattern, got 
$not_regexz*$not_regex requires a string pattern, got zUnknown operator: )
isinstancedict	TypeErrortyper-   
ValueErrorlistlenr5   	from_dictnextiteritemsstrKeyis_innot_inintfloatboolcontainsnot_containsregex	not_regex)r>   c
conditionsresultr   	conditionopvalues           r)   rV   Where.from_dictF   se   * $%%;DJ<O<O;PQRR9:: T>d6lD11/T&\0B0K0K/LM  4< A% !GHH4y1} P  7;6lCl%//!,lJC:!#!!}$]F^ $Md]d5k400":4U;L;U;U:V WXX4;1$ !FGG4y1} O  7;5kBk%//!,kJB:!#!!}$]F^ $M 4yA~ Ec$i[Q   $D$67EeS))7U8L8L7MN  )T** $3E7:KL  y>Q&$3E7:]^  !ioo&7!89	;u:..5[u:..5[u:--6\u:..5[u:--6\u:..5[%eT22'7U8L8L7MN  u:++E226\%eT22'8e9M9M8NO  u:,,U33;&%ec3t-DEE'QRVW\R]RfRfQgh  u:..u55?*%ec3t-DEE'UVZ[`VaVjVjUkl  u:225998^%eS11'DT%[EYEYDZ[  u:++E22<'%eS11'HeI]I]H^_  u://66$'9"%>?? 5zY..S D$ Cs   	VVc                 @   [        U [        5      (       aP  [        U[        5      (       a"  [        U R                  UR                  -   5      $ [        U R                  U/-   5      $ [        U[        5      (       a  [        U /UR                  -   5      $ [        X/5      $ )zOverload & operator for AND)rO   Andrf   r(   others     r)   __and__Where.__and__   s     dC  %%%4??U-=-==>>t%011s##v 0 0011D=!!r+   c                 @   [        U [        5      (       aP  [        U[        5      (       a"  [        U R                  UR                  -   5      $ [        U R                  U/-   5      $ [        U[        5      (       a  [        U /UR                  -   5      $ [        X/5      $ )zOverload | operator for OR)rO   Orrf   rn   s     r)   __or__Where.__or__   s     dB%$$$//E,<,<<==doo/00r""tfu///004-  r+   r,   N)ro   r5   r"   rm   )ro   r5   r"   rs   )r-   r.   r/   r0   __doc__r   rZ   r	   r;   staticmethodrV   rp   rt   r3   r,   r+   r)   r5   r5   +   sV    *Ic3h I P/S#X P/7 P/ P/d"!r+   r5   c                   B    \ rS rSr% Sr\\   \S'   S\\	\
4   4S jrSrg)rm      z(Logical AND of multiple where conditionsrf   r"   c                 d    SU R                    Vs/ s H  oR                  5       PM     sn0$ s  snf )Nr@   rf   r;   r(   re   s     r)   r;   And.to_dict   s'    doo>oo>??>   -r,   Nr-   r.   r/   r0   rv   r   r5   r1   r   rZ   r	   r;   r3   r,   r+   r)   rm   rm      s%    2U@c3h @r+   rm   c                   B    \ rS rSr% Sr\\   \S'   S\\	\
4   4S jrSrg)rs      z'Logical OR of multiple where conditionsrf   r"   c                 d    SU R                    Vs/ s H  oR                  5       PM     sn0$ s  snf )NrB   r{   r|   s     r)   r;   
Or.to_dict  s'    T__=_		_=>>=r~   r,   Nr   r,   r+   r)   rs   rs      s#    1U?c3h ?r+   rs   c                   F    \ rS rSr% Sr\\S'   \\S'   S\\\4   4S jr	Sr
g)	Eqi
  zEquality comparisonkeyrj   r"   c                 6    U R                   SU R                  00$ )NrC   r   rj   r'   s    r)   r;   
Eq.to_dict      5$**-..r+   r,   Nr-   r.   r/   r0   rv   rZ   r1   r	   r   r;   r3   r,   r+   r)   r   r   
  s#    	HJ/c3h /r+   r   c                   F    \ rS rSr% Sr\\S'   \\S'   S\\\4   4S jr	Sr
g)	Nei  zNot equal comparisonr   rj   r"   c                 6    U R                   SU R                  00$ )NrD   r   r'   s    r)   r;   
Ne.to_dict  r   r+   r,   Nr   r,   r+   r)   r   r     #    	HJ/c3h /r+   r   c                   F    \ rS rSr% Sr\\S'   \\S'   S\\\4   4S jr	Sr
g)	Gti   zGreater than comparisonr   rj   r"   c                 6    U R                   SU R                  00$ )NrE   r   r'   s    r)   r;   
Gt.to_dict'  r   r+   r,   Nr   r,   r+   r)   r   r      s#    !	HJ/c3h /r+   r   c                   F    \ rS rSr% Sr\\S'   \\S'   S\\\4   4S jr	Sr
g)	Gtei+  z Greater than or equal comparisonr   rj   r"   c                 6    U R                   SU R                  00$ )NrF   r   r'   s    r)   r;   Gte.to_dict2      64::.//r+   r,   Nr   r,   r+   r)   r   r   +  s#    *	HJ0c3h 0r+   r   c                   F    \ rS rSr% Sr\\S'   \\S'   S\\\4   4S jr	Sr
g)	Lti6  zLess than comparisonr   rj   r"   c                 6    U R                   SU R                  00$ )NrG   r   r'   s    r)   r;   
Lt.to_dict=  r   r+   r,   Nr   r,   r+   r)   r   r   6  r   r+   r   c                   F    \ rS rSr% Sr\\S'   \\S'   S\\\4   4S jr	Sr
g)	LteiA  zLess than or equal comparisonr   rj   r"   c                 6    U R                   SU R                  00$ )NrH   r   r'   s    r)   r;   Lte.to_dictH  r   r+   r,   Nr   r,   r+   r)   r   r   A  s#    '	HJ0c3h 0r+   r   c                   L    \ rS rSr% Sr\\S'   \\   \S'   S\	\\4   4S jr
Srg)	IniL  z"In comparison - value is in a listr   valuesr"   c                 6    U R                   SU R                  00$ )NrI   r   r   r'   s    r)   r;   
In.to_dictS  s    5$++.//r+   r,   Nr-   r.   r/   r0   rv   rZ   r1   r   r	   r   r;   r3   r,   r+   r)   r   r   L  s(    ,	HI0c3h 0r+   r   c                   L    \ rS rSr% Sr\\S'   \\   \S'   S\	\\4   4S jr
Srg)	NiniW  z*Not in comparison - value is not in a listr   r   r"   c                 6    U R                   SU R                  00$ )NrJ   r   r'   s    r)   r;   Nin.to_dict^  s    64;;/00r+   r,   Nr   r,   r+   r)   r   r   W  s(    4	HI1c3h 1r+   r   c                   F    \ rS rSr% Sr\\S'   \\S'   S\\\	4   4S jr
Srg)	Containsib  zEContains comparison for document content or metadata array membershipr   rj   r"   c                 6    U R                   SU R                  00$ )NrK   r   r'   s    r)   r;   Contains.to_dicti  s    ;

344r+   r,   Nr-   r.   r/   r0   rv   rZ   r1   r   r   r	   r;   r3   r,   r+   r)   r   r   b  s$    O	H5c3h 5r+   r   c                   F    \ rS rSr% Sr\\S'   \\S'   S\\\	4   4S jr
Srg)	NotContainsim  zINot-contains comparison for document content or metadata array membershipr   rj   r"   c                 6    U R                   SU R                  00$ )NrL   r   r'   s    r)   r;   NotContains.to_dictt  s    ?DJJ788r+   r,   Nr   r,   r+   r)   r   r   m  s$    S	H9c3h 9r+   r   c                   F    \ rS rSr% Sr\\S'   \\S'   S\\\4   4S jr	Sr
g)	Regexix  zRegular expression matchingr   patternr"   c                 6    U R                   SU R                  00$ )NrM   r   r   r'   s    r)   r;   Regex.to_dict  s    8T\\233r+   r,   Nr-   r.   r/   r0   rv   rZ   r1   r   r	   r;   r3   r,   r+   r)   r   r   x  s#    %	HL4c3h 4r+   r   c                   F    \ rS rSr% Sr\\S'   \\S'   S\\\4   4S jr	Sr
g)	NotRegexi  z$Negative regular expression matchingr   r   r"   c                 6    U R                   SU R                  00$ )NrN   r   r'   s    r)   r;   NotRegex.to_dict  s    <677r+   r,   Nr   r,   r+   r)   r   r     s#    .	HL8c3h 8r+   r   c                   L   \ rS rSr% SrS \S'   S \S'   S \S'   S \S'   S \S'   S\4S	 jrS
\4S jr	S\
S
\4S jrS\
S
\4S jrS\
S
\4S jrS\
S
\4S jrS\
S
\4S jrS\
S
\4S jrS\\
   S
\4S jrS\\
   S
\4S jrS\S
\4S jrS\S
\4S jrS\ S
\!4S jr"S\ S
\#4S jr$Sr%g)r[   i  a;  Field proxy for building Where filter expressions.

The Key class allows for readable field references using either:
1. Predefined constants for special fields: K.EMBEDDING, K.DOCUMENT, K.SCORE, etc.
2. String literals with # prefix for special fields: Key("#embedding")
3. Metadata field names without # prefix: Key("my_metadata_field")

Predefined field constants (special fields with # prefix):
    Key.ID - ID field (equivalent to Key("#id"))
    Key.DOCUMENT - Document field (equivalent to Key("#document"))
    Key.EMBEDDING - Embedding field (equivalent to Key("#embedding"))
    Key.METADATA - Metadata field (equivalent to Key("#metadata"))
    Key.SCORE - Score field (equivalent to Key("#score"))

Note: K is an alias for Key, so you can use K.DOCUMENT or Key.DOCUMENT interchangeably.

Examples:
    # Using predefined keys with K alias for special fields
    from chromadb.execution.expression import K
    K.DOCUMENT.contains("search text")  # Searches document field

    # Custom metadata field names (without # prefix)
    K("status") == "active"  # Metadata field named "status"
    K("category").is_in(["science", "tech"])  # Metadata field named "category"
    K("sparse_embedding")  # Example: metadata field (could store anything)

    # Using with Knn for different fields
    Knn(query=[0.1, 0.2])  # Default: searches "#embedding"
    Knn(query=[0.1, 0.2], key=K.EMBEDDING)  # Explicit: searches "#embedding"
    Knn(query=sparse, key="sparse_embedding")  # Example: searches a metadata field

    # Combining conditions
    (K("status") == "active") & (K.SCORE > 0.5)
IDDOCUMENT	EMBEDDINGMETADATASCOREnamec                     Xl         g )Nr   )r(   r   s     r)   __init__Key.__init__  s    	r+   r"   c                 ,    [        U R                  5      $ )z!Make Key hashable for use in sets)hashr   r'   s    r)   __hash__Key.__hash__  s    DIIr+   rj   c                 .    [        U R                  U5      $ )zEquality: Key('field') == value)r   r   r(   rj   s     r)   __eq__
Key.__eq__      $))U##r+   c                 .    [        U R                  U5      $ )z Not equal: Key('field') != value)r   r   r   s     r)   __ne__
Key.__ne__  r   r+   c                 .    [        U R                  U5      $ )z"Greater than: Key('field') > value)r   r   r   s     r)   __gt__
Key.__gt__  r   r+   c                 .    [        U R                  U5      $ )z,Greater than or equal: Key('field') >= value)r   r   r   s     r)   __ge__
Key.__ge__      499e$$r+   c                 .    [        U R                  U5      $ )zLess than: Key('field') < value)r   r   r   s     r)   __lt__
Key.__lt__  r   r+   c                 .    [        U R                  U5      $ )z)Less than or equal: Key('field') <= value)r   r   r   s     r)   __le__
Key.__le__  r   r+   r   c                 .    [        U R                  U5      $ )z?Check if field value is in list: Key('field').is_in(['a', 'b']))r   r   r(   r   s     r)   r\   	Key.is_in  s    $))V$$r+   c                 .    [        U R                  U5      $ )zDCheck if field value is not in list: Key('field').not_in(['a', 'b']))r   r   r   s     r)   r]   
Key.not_in  s    499f%%r+   r   c                 .    [        U R                  U5      $ )z9Match field against regex: Key('field').regex('^pattern'))r   r   r(   r   s     r)   rc   	Key.regex  s    TYY((r+   c                 .    [        U R                  U5      $ )z@Field should not match regex: Key('field').not_regex('^pattern'))r   r   r   s     r)   rd   Key.not_regex  s    		7++r+   c                     U R                   S:X  a   [        U[        5      (       d  [        S5      e[	        U R                   U5      $ )a  Check if field contains a value.

On Key.DOCUMENT: substring search (value must be a string).
On metadata fields: checks if the array field contains the scalar value.

Examples:
    Key.DOCUMENT.contains("machine learning")  # document substring
    Key("tags").contains("action")              # metadata array contains
    Key("scores").contains(42)                  # metadata array contains
	#documentz0$contains on #document requires a string pattern)r   rO   rZ   rQ   r   r   s     r)   ra   Key.contains  s9     99#Juc,B,BNOO		5))r+   c                     U R                   S:X  a   [        U[        5      (       d  [        S5      e[	        U R                   U5      $ )a^  Check if field does not contain a value.

On Key.DOCUMENT: excludes documents containing the substring.
On metadata fields: checks that the array field does not contain the scalar value.

Examples:
    Key.DOCUMENT.not_contains("deprecated")  # document substring exclusion
    Key("tags").not_contains("draft")         # metadata array not-contains
r   z4$not_contains on #document requires a string pattern)r   rO   rZ   rQ   r   r   s     r)   rb   Key.not_contains  s9     99#Juc,B,BRSS499e,,r+   r   N)&r-   r.   r/   r0   rv   r1   rZ   r   r^   r   r	   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r\   r   r]   r   rc   r   rd   r   r   ra   r   rb   r3   r,   r+   r)   r[   r[     s(   !H 	IOOLS # 
$C $B $$C $B $$C $B $%C %C %$C $B $%C %C %
%DI %" %&T#Y &3 &)S )U ), , ,*l *x *-, -; -r+   r[   #idr   
#embedding	#metadata#scorec                   R    \ rS rSr% Sr\\   \S'   Sr\\	   \S'   Sr
\\	   \S'   Srg)Filteri  Nuser_idswherewhere_documentr,   )r-   r.   r/   r0   r   r   r   r1   r   r	   r   r3   r,   r+   r)   r   r     s,    "Hhsm"E8C=$(NHSM(r+   r   c                   *    \ rS rSr% \\S'   \\S'   Srg)KNNi  
embeddingsfetchr,   N)r-   r.   r/   r0   r   r1   r^   r3   r,   r+   r)   r   r     s    Jr+   r   c                   v    \ rS rSr% Sr\\S'   Sr\\   \S'   S\	\
\4   4S jr\S\	\
\4   SS 4S	 j5       rS
rg)Limiti!  r   offsetNlimitr"   c                 Z    SU R                   0nU R                  b  U R                  US'   U$ )z8Convert the Limit to a dictionary for JSON serializationr  r  r  r  r(   rg   s     r)   r;   Limit.to_dict&  s,    DKK(::!"jjF7Or+   r>   c                 ^   [        U [        5      (       d!  [        S[        U 5      R                   35      eU R                  SS5      n[        U[        5      (       d!  [        S[        U5      R                   35      eUS:  a  [        SU 35      eU R                  S5      nUbJ  [        U[        5      (       d!  [        S[        U5      R                   35      eUS::  a  [        SU 35      eSS1n[        U R                  5       5      U-
  nU(       a  [        S	U 35      e[        XS
9$ )zCreate Limit from dictionary.

Examples:
- {"offset": 10} -> Limit(offset=10)
- {"offset": 10, "limit": 20} -> Limit(offset=10, limit=20)
- {"limit": 20} -> Limit(offset=0, limit=20)
zExpected dict for Limit, got r  r   z%Limit offset must be an integer, got z'Limit offset must be non-negative, got r  z$Limit limit must be an integer, got z"Limit limit must be positive, got zUnexpected keys in Limit dict: r  )rO   rP   rQ   rR   r-   getr^   rS   setkeysr  )r>   r  r  allowed_keysunexpected_keyss        r)   rV   Limit.from_dict-  s,    $%%;DJ<O<O;PQRR(A&&#&&7V8M8M7NO  A:FvhOPP!eS)):4;;O;O:PQ  z #EeW!MNN !'*diik*\9>>OPQQF00r+   r,   )r-   r.   r/   r0   r  r^   r1   r  r   r   rZ   r	   r;   rw   rV   r3   r,   r+   r)   r  r  !  sW    FCOE8C=c3h  "1S#X "17 "1 "1r+   r  c                   t    \ rS rSr% Sr\\S'   Sr\\S'   Sr\\S'   Sr	\\S'   Sr
\\S'   \S\4S	 j5       rS
rg)
ProjectioniS  Fdocument	embeddingr    rankurir"   c                 n   [        5       nU R                  (       a  UR                  S5        U R                  (       a  UR                  S5        U R                  (       a  UR                  S5        U R
                  (       a  UR                  S5        U R                  (       a  UR                  S5        U$ )N	documentsr   	metadatas	distancesuris)rT   r  appendr  r    r  r  )r(   includess     r)   includedProjection.included[  sm    6==OOK(>>OOL)==OOK(99OOK(88OOF#r+   r,   N)r-   r.   r/   r0   r  r`   r1   r  r    r  r  r2   r   r  r3   r,   r+   r)   r  r  S  sM    HdItHdD$C'  r+   r  c                      \ rS rSrSrS\\\4   4S jr\	S\\\4   SS 4S j5       r
S\S \\4   SS4S	 jrS\\\4   SS4S
 jrS\S \\4   SS4S jrS\\\4   SS4S jrS\S \\4   SS4S jrS\\\4   SS4S jrS\S \\4   SS4S jrS\\\4   SS4S jrSS jrS S jrS S jrS!S jrS"S jrS\S \\4   SS4S jrS\S \\4   SS4S jrSrg)#Rankil  a  Base class for rank expressions.

Supports arithmetic operations for combining rank expressions:
    - Addition: rank1 + rank2, rank + 0.5
    - Subtraction: rank1 - rank2, rank - 0.5
    - Multiplication: rank1 * rank2, rank * 0.8
    - Division: rank1 / rank2, rank / 2.0
    - Negation: -rank
    - Absolute value: abs(rank)

Supports mathematical functions:
    - Exponential: rank.exp()
    - Logarithm: rank.log()
    - Maximum: rank.max(other)
    - Minimum: rank.min(other)

Examples:
    # Weighted combination
    Knn(query=[0.1, 0.2]) * 0.8 + Val(0.5) * 0.2

    # Normalization
    Knn(query=[0.1, 0.2]) / Val(10.0)

    # Clamping
    Knn(query=[0.1, 0.2]).min(1.0).max(0.0)
r"   c                     [        S5      e)zCConvert the Score expression to a dictionary for JSON serializationr8   r9   r'   s    r)   r;   Rank.to_dict  r=   r+   r>   c                    [        U [        5      (       d!  [        S[        U 5      R                   35      eU (       d  [        S5      e[        U 5      S:w  a  [        S[        U 5       35      e[        [        U R                  5       5      5      nUS:X  aL  U S   n[        U[        [        45      (       d!  [        S[        U5      R                   35      e[        U5      $ US:X  GaF  U S   n[        U[        5      (       d!  [        S[        U5      R                   35      eS	U;  a  [        S
5      eUS	   n[        U[        5      (       aP  UR                  [        5      [        :X  a  [         R"                  " U5      nO[        S[         S[         SU 35      e[        U[$        [&        [(        R*                  45      (       a=  [-        U5      nU(       a  [        U5      S:  a  [        S5      e[/        U5        US   nO![        S[        U5      R                   35      eUR                  SS5      n[        U[0        5      (       d!  [        S[        U5      R                   35      eUR                  SS5      n[        U[        5      (       d!  [        S[        U5      R                   35      eUS::  a  [        SU 35      eUR                  SS5      n[        U[2        5      (       d!  [        S[        U5      R                   35      e[5        UUUUR                  S5      US9$ US:X  a  U S   n	[        U	[$        [&        45      (       d!  [        S[        U	5      R                   35      e[        U	5      S:  a  [        S [        U	5       35      eU	 V
s/ s H  n
[6        R#                  U
5      PM     nn
US   nUSS!  H  n
X-   nM	     U$ US":X  a  U S"   n[        U[        5      (       d!  [        S#[        U5      R                   35      eS$U;  d  S%U;  a  [        S&5      e[6        R#                  US$   5      n[6        R#                  US%   5      nX-
  $ US':X  a  U S'   n	[        U	[$        [&        45      (       d!  [        S([        U	5      R                   35      e[        U	5      S:  a  [        S)[        U	5       35      eU	 V
s/ s H  n
[6        R#                  U
5      PM     nn
US   nUSS!  H  n
X-  nM	     U$ US*:X  a  U S*   n[        U[        5      (       d!  [        S+[        U5      R                   35      eS$U;  d  S%U;  a  [        S,5      e[6        R#                  US$   5      n[6        R#                  US%   5      nX-  $ US-:X  aY  U S-   n[        U[        5      (       d!  [        S.[        U5      R                   35      e[9        [6        R#                  U5      5      $ US/:X  a^  U S/   n[        U[        5      (       d!  [        S0[        U5      R                   35      e[6        R#                  U5      R;                  5       $ US1:X  a^  U S1   n[        U[        5      (       d!  [        S2[        U5      R                   35      e[6        R#                  U5      R=                  5       $ US3:X  a  U S3   n	[        U	[$        [&        45      (       d!  [        S4[        U	5      R                   35      e[        U	5      S:  a  [        S5[        U	5       35      eU	 V
s/ s H  n
[6        R#                  U
5      PM     nn
US   nUSS!  H  n
UR?                  U
5      nM     U$ US6:X  a  U S6   n	[        U	[$        [&        45      (       d!  [        S7[        U	5      R                   35      e[        U	5      S:  a  [        S8[        U	5       35      eU	 V
s/ s H  n
[6        R#                  U
5      PM     nn
US   nUSS!  H  n
URA                  U
5      nM     U$ [        S9U 35      es  sn
f s  sn
f s  sn
f s  sn
f ):a  Create Rank expression from dictionary.

Supports operators:
- {"$val": number} -> Val(number)
- {"$knn": {...}} -> Knn(...)
- {"$sum": [ranks]} -> rank1 + rank2 + ...
- {"$sub": {"left": ..., "right": ...}} -> left - right
- {"$mul": [ranks]} -> rank1 * rank2 * ...
- {"$div": {"left": ..., "right": ...}} -> left / right
- {"$abs": rank} -> abs(rank)
- {"$exp": rank} -> rank.exp()
- {"$log": rank} -> rank.log()
- {"$max": [ranks]} -> rank1.max(rank2).max(rank3)...
- {"$min": [ranks]} -> rank1.min(rank2).min(rank3)...
zExpected dict for Rank, got zRank dict cannot be emptyrA   z1Rank dict must contain exactly one operator, got $valz$val requires a number, got $knnz$knn requires a dict, got queryz$knn requires 'query' fieldzExpected dict with z='z', got z)$knn requires exactly one query embeddingr   zB$knn query must be a list, numpy array, or SparseVector dict, got r   r   z$knn key must be a string, got r     z#$knn limit must be an integer, got z!$knn limit must be positive, got return_rankFz($knn return_rank must be a boolean, got default)r&  r   r  r)  r(  $sumz$sum requires a list, got    z$$sum requires at least 2 ranks, got N$subz2$sub requires a dict with 'left' and 'right', got leftrightz'$sub requires 'left' and 'right' fields$mulz$mul requires a list, got z$$mul requires at least 2 ranks, got $divz2$div requires a dict with 'left' and 'right', got z'$div requires 'left' and 'right' fields$absz$abs requires a rank dict, got $expz$exp requires a rank dict, got $logz$log requires a rank dict, got $maxz$max requires a list, got z$$max requires at least 2 ranks, got $minz$min requires a list, got z$$min requires at least 2 ranks, got zUnknown rank operator: )!rO   rP   rQ   rR   r-   rS   rU   rW   rX   r  r^   r_   Valr
  r   r   r   rV   rT   tuplenpndarrayr   r   rZ   r`   Knnr   absexplogmaxmin)r>   ri   rj   knn_datar&  
normalizedr   r  r(  
ranks_datarranksrg   sub_datar-  r.  div_data
child_datas                     r)   rV   Rank.from_dict  s   " $%%:4:;N;N:OPQQ899t9>CCI;O  $tyy{#$<LEec5\22">tE{?S?S>T UVVu:6\F|Hh--"<T(^=T=T<U VWWh& !>??W%E%&&99X&*BB(2259E %-hZr:R9SSZ[`Zab  ED%#<==1%8
!S_q%8$%PQQ $J/"1  XY]^cYdYmYmXno  ,,ul3Cc3''"A$s)BTBTAU VWWLL"-EeS))9$u+:N:N9OP  z #DUG!LMM",,}e<Kk400>tK?P?Y?Y>Z[   Y/'  6\fJj4-880j1A1J1J0KL  :" :3z?:KL  1;;
1T^^A&
E;1XF12Y M6\F|Hh--HhI`I`Hab  X%)@ !JKK>>(6"23DNN8G#45E<6\fJj4-880j1A1J1J0KL  :" :3z?:KL  1;;
1T^^A&
E;1XF12Y M6\F|Hh--HhI`I`Hab  X%)@ !JKK>>(6"23DNN8G#45E<6\fJj$//5d:6F6O6O5PQ  t~~j1226\fJj$//5d:6F6O6O5PQ  >>*-11336\fJj$//5d:6F6O6O5PQ  >>*-11336\fJj4-880j1A1J1J0KL  :" :3z?:KL  1;;
1T^^A&
E;1XF12YA M6\fJj4-880j1A1J1J0KL  :" :3z?:KL  1;;
1T^^A&
E;1XF12YA M 6rd;<<Y << <l <" <s   !`;a 2a(a
ro   Sumc                    [        U[        [        45      (       a  [        U5      OUn[        U [        5      (       aP  [        U[        5      (       a"  [	        U R
                  UR
                  -   5      $ [	        U R
                  U/-   5      $ [        U[        5      (       a  [	        U /UR
                  -   5      $ [	        X/5      $ )z'Addition: rank1 + rank2 or rank + value)rO   r^   r_   r6  rI  rD  r(   ro   
other_ranks      r)   __add__Rank.__add__i      #-ec5\#B#BSZ
dC  *c**4::
(8(8899tzzZL011
C((v
 0 0011D%&&r+   c                     [        U5      U -   $ )zRight addition: value + rankr6  rn   s     r)   __radd__Rank.__radd__u      5zD  r+   Subc                 h    [        U[        [        45      (       a  [        U5      OUn[	        X5      $ )z*Subtraction: rank1 - rank2 or rank - value)rO   r^   r_   r6  rU  rK  s      r)   __sub__Rank.__sub__y  (    #-ec5\#B#BSZ
4$$r+   c                 ,    [        [        U5      U 5      $ )zRight subtraction: value - rank)rU  r6  rn   s     r)   __rsub__Rank.__rsub__~      3u:t$$r+   Mulc                    [        U[        [        45      (       a  [        U5      OUn[        U [        5      (       aP  [        U[        5      (       a"  [	        U R
                  UR
                  -   5      $ [	        U R
                  U/-   5      $ [        U[        5      (       a  [	        U /UR
                  -   5      $ [	        X/5      $ )z-Multiplication: rank1 * rank2 or rank * value)rO   r^   r_   r6  r^  rD  rK  s      r)   __mul__Rank.__mul__  rO  r+   c                     [        U5      U -  $ )z"Right multiplication: value * rankrQ  rn   s     r)   __rmul__Rank.__rmul__  rT  r+   Divc                 h    [        U[        [        45      (       a  [        U5      OUn[	        X5      $ )z'Division: rank1 / rank2 or rank / value)rO   r^   r_   r6  re  rK  s      r)   __truediv__Rank.__truediv__  rY  r+   c                 ,    [        [        U5      U 5      $ )zRight division: value / rank)re  r6  rn   s     r)   __rtruediv__Rank.__rtruediv__  r]  r+   c                 .    [        [        S5      U /5      $ )z)Negation: -rank (equivalent to -1 * rank))r^  r6  r'   s    r)   __neg__Rank.__neg__  s    CGT?##r+   c                     [        U 5      $ )zAbsolute value: abs(rank)Absr'   s    r)   __abs__Rank.__abs__      4yr+   c                     [        U 5      $ )z"Absolute value builder: rank.abs()rq  r'   s    r)   r;  Rank.abs  ru  r+   c                     [        U 5      $ )zExponential: e^rank)Expr'   s    r)   r<  Rank.exp  ru  r+   c                     [        U 5      $ )zNatural logarithm: ln(rank))Logr'   s    r)   r=  Rank.log  ru  r+   Maxc                    [        U[        [        45      (       a  [        U5      OUn[        U [        5      (       aP  [        U[        5      (       a"  [	        U R
                  UR
                  -   5      $ [	        U R
                  U/-   5      $ [        U[        5      (       a  [	        U /UR
                  -   5      $ [	        X/5      $ )z1Maximum of this rank and another: rank.max(rank2))rO   r^   r_   r6  r~  rD  rK  s      r)   r>  Rank.max      #-ec5\#B#BSZ
 dC  *c**4::
(8(8899tzzZL011
C((v
 0 0011D%&&r+   Minc                    [        U[        [        45      (       a  [        U5      OUn[        U [        5      (       aP  [        U[        5      (       a"  [	        U R
                  UR
                  -   5      $ [	        U R
                  U/-   5      $ [        U[        5      (       a  [	        U /UR
                  -   5      $ [	        X/5      $ )z1Minimum of this rank and another: rank.min(rank2))rO   r^   r_   r6  r  rD  rK  s      r)   r?  Rank.min  r  r+   r,   N)r"   r^  )r"   rr  )r"   ry  )r"   r|  )r-   r.   r/   r0   rv   r   rZ   r	   r;   rw   rV   r
   r_   r^   rM  rR  rW  r[  r`  rc  rg  rj  rn  rs  r;  r<  r=  r>  r?  r3   r,   r+   r)   r   r   l  s   6Ic3h I X=S#X X=6 X= X=v
'U65##56 
'5 
'!eE3J/ !E !%U65##56 %5 %
%eE3J/ %E %
'U65##56 
'5 
'!eE3J/ !E !%vuc'9!: %u %
%%s
"3 % %$
'vuc12 'u ''vuc12 'u 'r+   r   c                   <    \ rS rSr% Sr\\S'   S\\\	4   4S jr
Srg)rr  i  zAbsolute value of a rankr  r"   c                 :    SU R                   R                  5       0$ )Nr1  r  r;   r'   s    r)   r;   Abs.to_dict      		))+,,r+   r,   Nr-   r.   r/   r0   rv   r   r1   r   rZ   r	   r;   r3   r,   r+   r)   rr  rr        "
J-c3h -r+   rr  c                   F    \ rS rSr% Sr\\S'   \\S'   S\\\	4   4S jr
Srg)	re  i  zDivision of two ranksr-  r.  r"   c                 p    SU R                   R                  5       U R                  R                  5       S.0$ )Nr0  r-  r.  r-  r;   r.  r'   s    r)   r;   Div.to_dict  ,    !2!2!4tzz?Q?Q?STUUr+   r,   Nr  r,   r+   r)   re  re    s%    
JKVc3h Vr+   re  c                   <    \ rS rSr% Sr\\S'   S\\\	4   4S jr
Srg)ry  i  zExponentiation of a rankr  r"   c                 :    SU R                   R                  5       0$ )Nr2  r  r'   s    r)   r;   Exp.to_dict  r  r+   r,   Nr  r,   r+   r)   ry  ry    r  r+   ry  c                   <    \ rS rSr% Sr\\S'   S\\\	4   4S jr
Srg)r|  i  zLogarithm of a rankr  r"   c                 :    SU R                   R                  5       0$ )Nr3  r  r'   s    r)   r;   Log.to_dict  r  r+   r,   Nr  r,   r+   r)   r|  r|    s    
J-c3h -r+   r|  c                   B    \ rS rSr% Sr\\   \S'   S\\	\
4   4S jrSrg)r~  i  zMaximum of multiple ranksrD  r"   c                 d    SU R                    Vs/ s H  oR                  5       PM     sn0$ s  snf )Nr4  rD  r;   r(   rC  s     r)   r;   Max.to_dict  '    djj9jj9::9r~   r,   Nr-   r.   r/   r0   rv   r   r   r1   r   rZ   r	   r;   r3   r,   r+   r)   r~  r~    #    #:;c3h ;r+   r~  c                   B    \ rS rSr% Sr\\   \S'   S\\	\
4   4S jrSrg)r  i  zMinimum of multiple ranksrD  r"   c                 d    SU R                    Vs/ s H  oR                  5       PM     sn0$ s  snf )Nr5  r  r  s     r)   r;   Min.to_dict  r  r~   r,   Nr  r,   r+   r)   r  r    r  r+   r  c                   B    \ rS rSr% Sr\\   \S'   S\\	\
4   4S jrSrg)r^  i  z Multiplication of multiple ranksrD  r"   c                 d    SU R                    Vs/ s H  oR                  5       PM     sn0$ s  snf )Nr/  r  r  s     r)   r;   Mul.to_dict  r  r~   r,   Nr  r,   r+   r)   r^  r^    s#    *:;c3h ;r+   r^  c                       \ rS rSr% Sr\\\\   \	SSS4   \
S'   \R                  r\\\4   \
S'   Sr\\
S	'   S
r\\   \
S'   Sr\\
S'   S\\\4   4S jrSrg
)r:  i  ak  KNN-based ranking expression.

Args:
    query: The query for KNN search. Can be:
           - A string (will be automatically embedded using the collection's embedding function)
           - A dense vector (list or numpy array)
           - A sparse vector (SparseVector dict)
    key: The embedding key to search against. Can be:
         - Key.EMBEDDING (default) - searches the main embedding field
         - A metadata field name (e.g., "my_custom_field") - searches that metadata field
    limit: Maximum number of results to consider (default: 16)
    default: Default score for records not in KNN results (default: None)
    return_rank: If True, return the rank position (0, 1, 2, ...) instead of distance (default: False)

Examples:
    # Search with string query (automatically embedded)
    Knn(query="hello world")  # Will use collection's embedding function

    # Search main embeddings with vectors (equivalent forms)
    Knn(query=[0.1, 0.2])  # Uses default key="#embedding"
    Knn(query=[0.1, 0.2], key=K.EMBEDDING)
    Knn(query=[0.1, 0.2], key="#embedding")

    # Search sparse embeddings stored in metadata with string
    Knn(query="hello world", key="custom_embedding")  # Will use schema's embedding function

    # Search sparse embeddings stored in metadata with vector
    Knn(query=my_vector, key="custom_embedding")  # Example: searches a metadata field
zNDArray[np.float32]zNDArray[np.float64]zNDArray[np.int32]r&  r   r'  r  Nr)  Fr(  r"   c                    U R                   n[        U[        5      (       a  UR                  5       nO/[        U[        R
                  5      (       a  UR                  5       nU R                  n[        U[        5      (       a  UR                  nXU R                  S.nU R                  b  U R                  US'   U R                  (       a  U R                  US'   SU0$ )N)r&  r   r  r)  r(  r%  )r&  rO   r   r;   r8  r9  tolistr   r[   r   r  r)  r(  )r(   query_value	key_valuerg   s       r)   r;   Knn.to_dict?  s    jjk<00%--/KRZZ00%,,.KHH	i%%!I '4::N <<# $F9$($4$4F=!r+   r,   )r-   r.   r/   r0   rv   r
   rZ   r   r_   r   r1   Kr   r   r[   r  r^   r)  r   r(  r`   r   r	   r;   r3   r,   r+   r)   r:  r:    s~    < U	  ;;CsCx&E3O#GXe_#K c3h  r+   r:  c                   F    \ rS rSr% Sr\\S'   \\S'   S\\\	4   4S jr
Srg)	rU  iY  zSubtraction of two ranksr-  r.  r"   c                 p    SU R                   R                  5       U R                  R                  5       S.0$ )Nr,  r  r  r'   s    r)   r;   Sub.to_dict`  r  r+   r,   Nr  r,   r+   r)   rU  rU  Y  s%    "
JKVc3h Vr+   rU  c                   B    \ rS rSr% Sr\\   \S'   S\\	\
4   4S jrSrg)rI  id  zSummation of multiple ranksrD  r"   c                 d    SU R                    Vs/ s H  oR                  5       PM     sn0$ s  snf )Nr*  r  r  s     r)   r;   Sum.to_dictj  r  r~   r,   Nr  r,   r+   r)   rI  rI  d  s#    %:;c3h ;r+   rI  c                   <    \ rS rSr% Sr\\S'   S\\\	4   4S jr
Srg)r6  in  zConstant rank valuerj   r"   c                     SU R                   0$ )Nr$  )rj   r'   s    r)   r;   Val.to_dictt  s    

##r+   r,   N)r-   r.   r/   r0   rv   r_   r1   r   rZ   r	   r;   r3   r,   r+   r)   r6  r6  n  s    L$c3h $r+   r6  c                   x    \ rS rSr% Sr\\   \S'   Sr\	\S'   Sr
\\\      \S'   Sr\\S	'   S
\\\4   4S jrSrg)Rrfix  aM  Reciprocal Rank Fusion for combining ranking strategies.

RRF formula: score = -sum(weight_i / (k + rank_i)) for each ranking strategy
The negative is used because RRF produces higher scores for better results,
but Chroma uses ascending order (lower scores = better results).

Args:
    ranks: List of Rank expressions to fuse (must have at least one)
    k: Smoothing constant (default: 60, standard in literature)
    weights: Optional weights for each ranking strategy. If not provided,
            all ranks are weighted equally (weight=1.0 each).
    normalize: If True, normalize weights to sum to 1.0 (default: False).
              When False, weights are used as-is for relative importance.
              When True, weights are scaled so they sum to 1.0.

Examples:
    # Note: metadata fields (like "sparse_embedding" below) are user-defined and can store any data.
    # The field name is just an example - use whatever name matches your metadata structure.
    # Basic RRF combining KNN rankings (equal weight)
    Rrf([
        Knn(query=[0.1, 0.2], return_rank=True),
        Knn(query=another_vector, key="custom_embedding", return_rank=True)  # Example metadata field
    ])

    # Weighted RRF with relative weights (not normalized)
    Rrf(
        ranks=[
            Knn(query=[0.1, 0.2], return_rank=True),
            Knn(query=another_vector, key="custom_embedding", return_rank=True)  # Example metadata field
        weights=[2.0, 1.0],  # First ranking is 2x more important
        k=100
    )

    # Weighted RRF with normalized weights
    Rrf(
        ranks=[
            Knn(query=[0.1, 0.2], return_rank=True),
            Knn(query=another_vector, key="custom_embedding", return_rank=True)  # Example metadata field
        ],
        weights=[3.0, 1.0],  # Will be normalized to [0.75, 0.25]
        normalize=True,
        k=100
    )
rD  <   kNweightsF	normalizer"   c                    U R                   (       d  [        S5      eU R                  S::  a  [        SU R                   35      eU R                  b  [	        U R                  5      [	        U R                   5      :w  a8  [        S[	        U R                  5       S[	        U R                   5       S35      e[        S U R                   5       5      (       a  [        S	5      eU R                  (       a  U R                  OS
/[	        U R                   5      -  nU R                  (       a0  [        U5      nUS:X  a  [        S5      eU Vs/ s H  o3U-  PM	     nn[        XR                   5       VVs/ s H  u  p4X0R                  U-   -  PM     nnnUS   nUSS  H  nXg-   nM	     U* R                  5       $ s  snf s  snnf )zConvert RRF to a composition of existing expression operators.

Builds: -sum(weight_i / (k + rank_i)) for each rank
Using Python's overloaded operators for cleaner code.
zRRF requires at least one rankr   zk must be positive, got NzNumber of weights (z) must match number of ranks ()c              3   *   #    U  H	  oS :  v   M     g7f)g        Nr,   ).0ws     r)   	<genexpr>Rrf.to_dict.<locals>.<genexpr>  s     1Lqs7Ls   z All weights must be non-negativeg      ?z3Sum of weights must be positive when normalize=TruerA   )
rD  rS   r  r  rU   anyr  sumzipr;   )r(   r  
weight_sumr  r  termsrrf_sumterms           r)   r;   Rrf.to_dict  s    zz=>>66Q;7x@AA <<#4<< C

O3 )#dll*;)<<Z[^_c_i_i[jZkklm  1DLL111 !CDD #',,$,,SEC

O4K >>WJQ !VWW/67w!:~wG7 584LM4Lfftm$4LM a!"IDnG  !!## 8 Ns   	F71F<r,   )r-   r.   r/   r0   rv   r   r   r1   r  r^   r  r   r_   r  r`   r   rZ   r	   r;   r3   r,   r+   r)   r  r  x  sN    +Z :AsK%)GXd5k")It($c3h ($r+   r  c                   ~    \ rS rSr% Sr\" \S9r\\	\
\4      \S'   S\\\4   4S jr\S\\\4   SS 4S j5       rS	rg
)Selecti  a  Selection configuration for search results.

Fields can be:
- Key.DOCUMENT - Select document key (equivalent to Key("#document"))
- Key.EMBEDDING - Select embedding key (equivalent to Key("#embedding"))
- Key.SCORE - Select score key (equivalent to Key("#score"))
- Any other string - Select specific metadata property

Note: You can use K as an alias for Key for more concise code.

Examples:
    # Select predefined keys using K alias (K is shorthand for Key)
    from chromadb.execution.expression import K
    Select(keys={K.DOCUMENT, K.SCORE})

    # Select specific metadata properties
    Select(keys={"title", "author", "date"})

    # Mixed selection
    Select(keys={K.DOCUMENT, "title", "author"})
default_factoryr  r"   c                     / nU R                    HF  n[        U[        5      (       a  UR                  UR                  5        M5  UR                  U5        MH     S[        [        R                  U5      5      0$ )z9Convert the Select to a dictionary for JSON serializationr  )r  rO   r[   r  r   rT   rP   fromkeys)r(   key_stringsr  s      r)   r;   Select.to_dict  s_     A!S!!""166*""1%	  T]];7899r+   r>   c                    [        U [        5      (       d!  [        S[        U 5      R                   35      eU R                  S/ 5      n[        U[        [        [        45      (       d!  [        S[        U5      R                   35      e/ nU GH  n[        U[        5      (       d!  [        S[        U5      R                   35      eUS:X  a!  UR                  [        R                  5        Ma  US:X  a!  UR                  [        R                  5        M  US:X  a!  UR                  [        R                  5        M  US:X  a!  UR                  [        R                  5        M  US	:X  a!  UR                  [        R                   5        M  UR                  [        U5      5        GM     S1n[        U R#                  5       5      U-
  nU(       a  [%        S
U 35      e['        [        U5      S9$ )zCreate Select from dictionary.

Examples:
- {"keys": ["#document", "#score"]} -> Select(keys={Key.DOCUMENT, Key.SCORE})
- {"keys": ["title", "author"]} -> Select(keys={"title", "author"})
zExpected dict for Select, got r  z*Select keys must be a list/tuple/set, got z!Select key must be a string, got r   r   r   r   r   z Unexpected keys in Select dict: )r  )rO   rP   rQ   rR   r-   r
  rT   r7  r  rZ   r  r[   r   r   r   r   r   r  rS   r  )r>   r  key_listr  r  r  s         r)   rV   Select.from_dict  s    $%%<T$Z=P=P<QRSSxx#$uc 233<T$Z=P=P<QR 
 Aa%%"CDGDTDTCU VWW Ez'k!-l".k!-h		* A'# ( xdiik*\9??PQRR 3x=))r+   r,   N)r-   r.   r/   r0   rv   r   r  r  r   r
   r[   rZ   r1   r   r	   r;   rw   rV   r3   r,   r+   r)   r  r    sc    , "'s!;D#eCHo
;
:c3h 
: ,*S#X ,*8 ,* ,*r+   r  r  r"   c                     [        [        [        [        [        4      [        U 5      5      nU Vs/ s H&  n[        U[        5      (       a  UR                  OUPM(     sn$ s  snf )z:Convert OneOrMany[Key|str] to List[str] for serialization.)r   r   r
   r[   rZ   r   rO   r   )r  	keys_listr  s      r)   _keys_to_stringsr  0  sN    T%S/*,B4,HII9BCAjC((AFFa/CCCs   -A".c                 r    U  Vs/ s H%  n[        U[        5      (       a  [        U5      OUPM'     sn$ s  snf )z3Convert List[str] to List[Key] for deserialization.)rO   rZ   r[   r  r  s     r)   _strings_to_keysr  6  s/    9=>AjC((CFa/>>>s   ,4ri   r>   c                 :   X   n[        U[        5      (       d#  [        U  S[        U5      R                   35      eSU;  a  [        U  S35      eSU;  a  [        U  S35      eUS   n[        U[        [        45      (       d#  [        U  S[        U5      R                   35      eU(       d  [        U  S35      eUS   n[        U[        5      (       d#  [        U  S[        U5      R                   35      eUS	::  a  [        U  S
U 35      e[        U5      U4$ )aT  Parse common fields for MinK/MaxK from dict.

Args:
    op: The operator name (e.g., "$min_k" or "$max_k")
    data: The dict containing the operator

Returns:
    Tuple of (keys, k) where keys is List[Union[Key, str]] and k is int

Raises:
    TypeError: If data types are invalid
    ValueError: If required fields are missing or invalid
z requires a dict, got r  z requires 'keys' fieldr  z requires 'k' fieldz keys must be a list, got z keys cannot be emptyz k must be an integer, got r   z k must be positive, got )
rO   rP   rQ   rR   r-   rS   rT   r7  r^   r  )ri   r>   agg_datar  r  s        r)   _parse_k_aggregater  ;  s)     xHh%%2$4T(^5L5L4MNOOXB45677
(B42344FDdT5M**2$8d9L9L8MNOOB44566Aa2$9$q':J:J9KLMMAvB48<==D!1$$r+   c                   V    \ rS rSrSrS\\\4   4S jr\	S\\\4   SS 4S j5       r
Srg)		Aggregateib  a	  Base class for aggregation expressions within groups.

Aggregations determine which records to keep from each group:
- MinK: Keep k records with minimum values (ascending order)
- MaxK: Keep k records with maximum values (descending order)

Examples:
    # Keep top 3 by score per group (single key)
    MinK(keys=Key.SCORE, k=3)

    # Keep top 5 by priority, then score as tiebreaker (multiple keys)
    MinK(keys=[Key("priority"), Key.SCORE], k=5)

    # Keep bottom 2 by score per group
    MaxK(keys=Key.SCORE, k=2)
r"   c                     [        S5      e)zGConvert the Aggregate expression to a dictionary for JSON serializationr8   r9   r'   s    r)   r;   Aggregate.to_dictu  r=   r+   r>   c                    [        U [        5      (       d!  [        S[        U 5      R                   35      eU (       d  [        S5      e[        U 5      S:w  a  [        S[        U 5       35      e[        [        U R                  5       5      5      nUS:X  a  [        X5      u  p#[        X#S9$ US:X  a  [        X5      u  p#[        X#S9$ [        SU 35      e)	zCreate Aggregate expression from dictionary.

Supports:
- {"$min_k": {"keys": [...], "k": n}} -> MinK(keys=[...], k=n)
- {"$max_k": {"keys": [...], "k": n}} -> MaxK(keys=[...], k=n)
z!Expected dict for Aggregate, got zAggregate dict cannot be emptyrA   z6Aggregate dict must contain exactly one operator, got $min_kr  $max_kzUnknown aggregate operator: )rO   rP   rQ   rR   r-   rS   rU   rW   rX   r  r  MinKMaxK)r>   ri   r  r  s       r)   rV   Aggregate.from_dicty  s     $%%?T
@S@S?TUVV=>>t9>HTT  $tyy{#$>(2GDT''8^(2GDT'';B4@AAr+   r,   N)r-   r.   r/   r0   rv   r   rZ   r	   r;   rw   rV   r3   r,   r+   r)   r  r  b  sK    "Ic3h I BS#X B; B Br+   r  c                   V    \ rS rSr% Sr\\\\4      \	S'   \
\	S'   S\\\4   4S jrSrg)	r  i  z:Keep k records with minimum aggregate key values per groupr  r  r"   c                 J    S[        U R                  5      U R                  S.0$ )Nr  r  r  r  r  r'   s    r)   r;   MinK.to_dict       #3DII#>TVVLMMr+   r,   Nr-   r.   r/   r0   rv   r   r
   r[   rZ   r1   r^   r   r	   r;   r3   r,   r+   r)   r  r    3    D
E#s(O
$$
FNc3h Nr+   r  c                   V    \ rS rSr% Sr\\\\4      \	S'   \
\	S'   S\\\4   4S jrSrg)	r  i  z:Keep k records with maximum aggregate key values per groupr  r  r"   c                 J    S[        U R                  5      U R                  S.0$ )Nr  r  r  r'   s    r)   r;   MaxK.to_dict  r  r+   r,   Nr  r,   r+   r)   r  r    r  r+   r  c                       \ rS rSr% Sr\" \S9r\\	\
\4      \S'   Sr\\   \S'   S\\\4   4S jr\S	\\\4   SS 4S
 j5       rSrg)GroupByi  a   Group results by metadata keys and aggregate within each group.

Groups search results by one or more metadata fields, then applies an
aggregation (MinK or MaxK) to select records within each group.
The final output is flattened and sorted by score.

Args:
    keys: Metadata key(s) to group by. Can be a single key or a list of keys.
          E.g., Key("category") or [Key("category"), Key("author")]
    aggregate: Aggregation to apply within each group (MinK or MaxK)

Note: Both keys and aggregate must be specified together.

Examples:
    # Top 3 documents per category (single key)
    GroupBy(
        keys=Key("category"),
        aggregate=MinK(keys=Key.SCORE, k=3)
    )

    # Top 2 per (year, category) combination (multiple keys)
    GroupBy(
        keys=[Key("year"), Key("category")],
        aggregate=MinK(keys=Key.SCORE, k=2)
    )

    # Top 1 per category by priority, score as tiebreaker
    GroupBy(
        keys=Key("category"),
        aggregate=MinK(keys=[Key("priority"), Key.SCORE], k=1)
    )
r  r  N	aggregater"   c                     U R                   (       a  U R                  c  0 $ S[        U R                   5      0nU R                  R                  5       US'   U$ )z:Convert the GroupBy to a dictionary for JSON serializationr  r  )r  r  r  r;   r  s     r)   r;   GroupBy.to_dict  sI     yyDNN2I"(*:499*E!F"nn446{r+   r>   c                 @   [        U [        5      (       d!  [        S[        U 5      R                   35      eU (       d
  [        5       $ SU ;  a  [        S5      eSU ;  a  [        S5      eU S   n[        U[        [        45      (       d!  [        S[        U5      R                   35      eU(       d  [        S5      eU S   n[        U[        5      (       d!  [        S[        U5      R                   35      e[        R                  U5      n[        [        U5      US	9$ )
zCreate GroupBy from dictionary.

Examples:
- {} -> GroupBy() (default, no grouping)
- {"keys": ["category"], "aggregate": {"$min_k": {"keys": ["#score"], "k": 3}}}
zExpected dict for GroupBy, got r  zGroupBy requires 'keys' fieldr  z"GroupBy requires 'aggregate' fieldz!GroupBy keys must be a list, got zGroupBy keys cannot be emptyz&GroupBy aggregate must be a dict, got )r  r  )rO   rP   rQ   rR   r-   r  rS   rT   r7  r  rV   r  )r>   r  aggregate_datar  s       r)   rV   GroupBy.from_dict  s    $%%=d4j>Q>Q=RSTT 9 <==d"ABBF|$u..?T
@S@S?TUVV;<<k*.$//8n9M9V9V8WX  ''7	,T2iHHr+   r,   )r-   r.   r/   r0   rv   r   rT   r  r   r
   r[   rZ   r1   r  r   r  r   r	   r;   rw   rV   r3   r,   r+   r)   r  r    sw    B (-T'BD)E#s(O
$B%)Ix	")c3h  !IS#X !I9 !I !Ir+   r  )Sdataclassesr   r   typingr   r   r   r   r	   r
   r   chromadb.base_typesr   numpyr8  numpy.typingr   chromadb.api.typesr   r   r   r   r   r   r   r   r   r   chromadb.typesr   r   r   r   r5   rm   rs   r   r   r   r   r   r   r   r   r   r   r   r   r[   r   r   r   r   r   r  r   r   r  r  r   rr  re  ry  r|  r~  r  r^  r:  rU  rI  r6  r  r  rZ   r  r7  r  r^   r  r  r  r  r  r,   r+   r)   <module>r     s:   ( > > > ,       
 
 
 G! G! G!T @% @ @ ? ? ? / / / / / / / / / 0% 0 0 / / / 0% 0 0 0 0 0 1% 1 1 5u 5 5 9% 9 9 4E 4 4 8u 8 8w- w-v 
U;L!;M	  ) ) )   
 .1 .1 .1b   0 [' [' ['|
 -$ - - V$ V V -$ - - -$ - - ;$ ; ; ;$ ; ; ;$ ; ; C $ C  C L V$ V V ;$ ; ; $$ $ $ [$$ [$ [$| R* R* R*pD9U38_5 D$s) D?5cE#s(O!;< ?eCQTHoAV ?
$%$%S>$%
4c3h #%&$%N 2B 2B 2Bj N9 N N N9 N N PI PI PIr+   