
    ei)                         d dl mZmZ d dlmZmZmZmZmZm	Z	 d dl
mZmZmZmZmZmZmZmZmZmZ e G d d             Ze G d d             Ze G d d	             Z G d
 d      Zy)    )	dataclassfield)ListDictAnyUnionSetOptional)
KNNFilterGroupByLimit
ProjectionScanRankSelectWhereKeyc                       e Zd ZU eed<   y)	CountPlanscanN)__name__
__module____qualname__r   __annotations__     l/home/obispo/Crisostomo_bridge/mision_env/lib/python3.12/site-packages/chromadb/execution/expression/plan.pyr   r      s    
Jr   r   c                   l    e Zd ZU eed<    ee      Zeed<    ee      Z	eed<    ee
      Ze
ed<   y)GetPlanr   default_factoryfilterlimit
projectionN)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                   Z    e Zd ZU eed<   eed<    ee      Zeed<    ee	      Z
e	ed<   y)KNNPlanr   knnr!   r#   r%   N)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                      e Zd ZdZ	 	 	 	 	 ddeeeeee	f   f      deee
eee	f   f      deeeeee	f   f      deeeeee	f   ef      deeeeee	f   ee   ee   f      f
dZd	eee	f   fd
ZddZdeeef   d	d fdZdeeeeee	f   f      d	d fdZdeee
eee	f   f      d	d fdZdeeeeee	f   f      d	d fdZddeded	d fdZy)Searcha{  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"))

    With group_by:
        (Search()
            .rank(Knn(query=[0.1, 0.2]))
            .group_by(GroupBy(
                keys=[Key("category")],
                aggregate=MinK(keys=[Key.SCORE], k=3)
            )))

    Empty Search() is valid and will use defaults:
        - where: None (no filtering)
        - rank: None (no ranking - results ordered by default order)
        - group_by: None (no grouping)
        - limit: No limit
        - select: Empty selection
    Nwhererankgroup_byr$   selectc                 R   |d| _         ndt        |t              r|| _         nLt        |t              rt        j                  |      | _         n!t        dt        |      j                         |d| _        ndt        |t              r|| _        nLt        |t              rt        j                  |      | _        n!t        dt        |      j                         |t               | _        ndt        |t              r|| _        nLt        |t              rt        j                  |      | _        n!t        dt        |      j                         |t               | _        nt        |t              r|| _        nzt        |t              rt        j                  |dd      | _        nLt        |t              rt        j                  |      | _        n!t        dt        |      j                         |t               | _        yt        |t              r|| _        yt        |t              rt        j                  |      | _        yt        |t"        t$        f      r&t        j                  dt#        |      i      | _        yt        d	t        |      j                         )
ah  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
            group_by: GroupBy configuration for grouping and aggregating results (defaults to None)
                      Dict will be converted using GroupBy.from_dict()
            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"])
        Nz1where must be a Where object, dict, or None, got z/rank must be a Rank object, dict, or None, got z6group_by must be a GroupBy 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   	_group_byr   _limitintr   _selectlistset)selfr+   r,   r-   r$   r.   s         r   __init__zSearch.__init__`   s   4 =DKu%DKt$//%0DKCDKDXDXCYZ 
 <DJd#DJd#-DJA$t*BUBUAVW 
 $YDN'*%DN$'$..x8DNHhI`I`Hab 
 ='DKu%DKs#//EQ*GHDKt$//%0DKHeI]I]H^_ 
 >!8DL'!DL%!++F3DLs,!++VT&\,BCDLPQUV\Q]QfQfPgh r   returnc                 :   | j                   | j                   j                         nd| j                  | j                  j                         nd| j                  j                         | j                  j                         | j
                  j                         dS )z9Convert the Search to a dictionary for JSON serializationN)r#   r,   r-   r$   r.   )r2   to_dictr8   r9   r:   r<   )r?   s    r   rC   zSearch.to_dict   st     04{{/Fdkk))+D,0JJ,BDJJ&&(..0[[((*ll**,
 	
r   c                    t        t        j                  t        j                  t        j                  t        j
                  h      }t        | j                  | j                  | j                  | j                  |      S )zASelect all predefined keys (document, embedding, metadata, score)r1   r+   r,   r-   r$   r.   )r   r   DOCUMENT	EMBEDDINGMETADATASCOREr*   r2   r8   r9   r:   )r?   
new_selects     r   
select_allzSearch.select_all   sQ    #,,s||SYY!WX
++^^++
 	
r   r1   c                     t        t        |            }t        | j                  | j                  | j
                  | j                  |      S )zSelect specific keys

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

        Returns:
            New Search object with updated select configuration
        rE   rF   )r   r>   r*   r2   r8   r9   r:   )r?   r1   rK   s      r   r.   zSearch.select   s>     T+
++^^++
 	
r   c                 r    t        || j                  | j                  | j                  | j                        S )a  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}}]})
        rF   )r*   r8   r9   r:   r<   )r?   r+   s     r   r+   zSearch.where   s0     ^^++<<
 	
r   	rank_exprc                 r    t        | j                  || j                  | j                  | j                        S )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}]})
        rF   )r*   r2   r9   r:   r<   )r?   rO   s     r   r,   zSearch.rank   s0     ++^^++<<
 	
r   c                 r    t        | j                  | j                  || j                  | j                        S )a#  Set the group_by configuration for grouping and aggregating results

        Args:
            group_by: A GroupBy object, dict, or None for grouping
                      Dicts will be converted using GroupBy.from_dict()

        Example:
            search.group_by(GroupBy(
                keys=[Key("category")],
                aggregate=MinK(keys=[Key.SCORE], k=3)
            ))
            search.group_by({
                "keys": ["category"],
                "aggregate": {"$min_k": {"keys": ["#score"], "k": 3}}
            })
        rF   )r*   r2   r8   r:   r<   )r?   r-   s     r   r-   zSearch.group_by  s0    " ++++<<
 	
r   r0   c                     t        ||      }t        | j                  | j                  | j                  || j
                        S )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)
        )r0   r$   rF   )r   r*   r2   r8   r9   r<   )r?   r$   r0   	new_limits       r   r$   zSearch.limit$  s<     u5	++^^<<
 	
r   )NNNNN)rA   r*   )r   )r   r   r   __doc__r
   r   r   r   strr   r   r   r   r;   r   r   r	   r@   rC   rL   r   r.   r+   r,   r-   r$   r   r   r   r*   r*   '   s   6t 9=6:=A=AOSXeT#s(^345X uT4S>123X 5$sCx.!89:	X
 eT#s(^S89:X vtCH~tCy#c(JKLXt
c3h 
	

E#s(O 
 
$
8E%c3h*?$@A 
h 
(
huT4S>-A'BC 
 
*
%c3h0G*H!I 
h 
2
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>rY      st    ( 8 8      ? ? ? ? ? ?N
 N
r   