o
    i:-                     @   s   d dl mZmZmZmZ d dlmZ e ZG dd dZ	G dd dZ
G dd dZG d	d
 d
eZG dd deZG dd dZG dd dZG dd dZdS )    )ListOptionalTupleUnion)DEFAULT_DIALECTc                   @   s,   e Zd Zd
dededdfddZdd	 ZdS )Limitr   offsetcountreturnNc                 C   s   || _ || _d S N)r   r	   )selfr   r	    r   U/home/ubuntu/.local/lib/python3.10/site-packages/redis/commands/search/aggregation.py__init__	   s   
zLimit.__init__c                 C   s    | j rdt| jt| j gS g S )NLIMIT)r	   strr   r   r   r   r   
build_args   s   zLimit.build_args)r   r   __name__
__module____qualname__intr   r   r   r   r   r   r      s    r   c                   @   sR   e Zd ZdZdZdeddfddZdedd fdd	Zede	ed
f fddZ
dS )Reducerzr
    Base reducer object for all reducers.

    See the `redisearch.reducers` module for the actual reducers.
    Nargsr
   c                 G   s   || _ d | _d | _d S r   )_args_field_aliasr   r   r   r   r   r         
zReducer.__init__aliasc                 C   s.   |t u r| jstd| jdd }|| _| S )a  
        Set the alias for this reducer.

        ### Parameters

        - **alias**: The value of the alias for this reducer. If this is the
            special value `aggregation.FIELDNAME` then this reducer will be
            aliased using the same name as the field upon which it operates.
            Note that using `FIELDNAME` is only possible on reducers which
            operate on a single field value.

        This method returns the `Reducer` object making it suitable for
        chaining.
        z(Cannot use FIELDNAME alias with no field   N)	FIELDNAMEr   
ValueErrorr   )r   r    r   r   r   r    "   s   zReducer.alias.c                 C   s   | j S r   )r   r   r   r   r   r   :   s   zReducer.args)r   r   r   __doc__NAMEr   r   r    propertyr   r   r   r   r   r   r      s    r   c                   @   s4   e Zd ZU dZdZee ed< deddfddZdS )SortDirectionz@
    This special class is used to indicate sort direction.
    N	DIRSTRINGfieldr
   c                 C   s
   || _ d S r   )r)   )r   r)   r   r   r   r   F   s   
zSortDirection.__init__)	r   r   r   r$   r(   r   r   __annotations__r   r   r   r   r   r'   ?   s   
 r'   c                   @      e Zd ZdZdZdS )AsczK
    Indicate that the given field should be sorted in ascending order
    ASCNr   r   r   r$   r(   r   r   r   r   r,   J       r,   c                   @   r+   )DesczL
    Indicate that the given field should be sorted in descending order
    DESCNr.   r   r   r   r   r0   R   r/   r0   c                   @   s  e Zd ZdZd-deddfddZdedd fd	d
Zdeeee f de	dd fddZ
d.ddZdededd fddZdedd fddZdeeee f dd fddZd.ddZd.ddZdedd fddZd.d d!Zd/d$ed%edd fd&d'Zdee fd(d)Zd*edd fd+d,ZdS )0AggregateRequestzH
    Aggregation request which can be passed to `Client.aggregate`.
    *queryr
   Nc                 C   sF   || _ g | _g | _d| _d| _d| _d| _g | _t| _	d| _
d| _dS )a}  
        Create an aggregation request. This request may then be passed to
        `client.aggregate()`.

        In order for the request to be usable, it must contain at least one
        group.

        - **query** Query string for filtering records.

        All member methods (except `build_args()`)
        return the object itself, making them useful for chaining.
        Fr   TFIDFN)_query_aggregateplan_loadfields_loadall_max_with_schema	_verbatim_cursorr   _dialect_add_scores_scorer)r   r4   r   r   r   r   _   s   
zAggregateRequest.__init__fieldsc                 G   s   |r
| j | | S d| _| S )aC  
        Indicate the fields to be returned in the response. These fields are
        returned in addition to any others implicitly specified.

        ### Parameters

        - **fields**: If fields not specified, all the fields will be loaded.
        Otherwise, fields should be given in the format of `@field`.
        T)r8   extendr9   )r   rA   r   r   r   loadx   s
   
zAggregateRequest.loadreducersc                 G   s   t |tr|gn|}dtt|g|}|D ]!}|d|jtt|jg7 }||j |jdur7|d|jg7 }q| j| | S )a|  
        Specify by which fields to group the aggregation.

        ### Parameters

        - **fields**: Fields to group by. This can either be a single string,
            or a list of strings. both cases, the field should be specified as
            `@field`.
        - **reducers**: One or more reducers. Reducers may be found in the
            `aggregation` module.
        GROUPBYREDUCENAS)
isinstancer   lenr%   r   rB   r   r7   )r   rA   rD   retreducerr   r   r   group_by   s   
zAggregateRequest.group_byc                 K   s>   |  D ]\}}d|g}|dur|d|g7 }| j| q| S )aQ  
        Specify one or more projection expressions to add to each result

        ### Parameters

        - **kwexpr**: One or more key-value pairs for a projection. The key is
            the alias for the projection, and the value is the projection
            expression itself, for example `apply(square_root="sqrt(@foo)")`
        APPLYNrG   )itemsr7   rB   )r   kwexprr    exprrJ   r   r   r   apply   s   
zAggregateRequest.applyr   numc                 C   s   t ||}| j|  | S )a  
        Sets the limit for the most recent group or query.

        If no group has been defined yet (via `group_by()`) then this sets
        the limit for the initial pool of results from the query. Otherwise,
        this limits the number of items operated on from the previous group.

        Setting a limit on the initial search results may be useful when
        attempting to execute an aggregation on a sample of a large data set.

        ### Parameters

        - **offset**: Result offset from which to begin paging
        - **num**: Number of results to return


        Example of sorting the initial results:

        ```
        AggregateRequest("@sale_amount:[10000, inf]")            .limit(0, 10)            .group_by("@state", r.count())
        ```

        Will only group by the states found in the first 10 results of the
        query `@sale_amount:[10000, inf]`. On the other hand,

        ```
        AggregateRequest("@sale_amount:[10000, inf]")            .limit(0, 1000)            .group_by("@state", r.count()            .limit(0, 10)
        ```

        Will group all the results matching the query, but only return the
        first 10 groups.

        If you only wish to return a *top-N* style query, consider using
        `sort_by()` instead.

        )r   r7   rB   r   )r   r   rR   _limitr   r   r   limit   s   
*zAggregateRequest.limitc                 O   s   g }|D ]}t |ttfr||j|jg7 }q||g7 }qdtt|g}|| |dd}|dkr;|dt|g7 }| j	| | S )a,  
        Indicate how the results should be sorted. This can also be used for
        *top-N* style queries

        ### Parameters

        - **fields**: The fields by which to sort. This can be either a single
            field or a list of fields. If you wish to specify order, you can
            use the `Asc` or `Desc` wrapper classes.
        - **max**: Maximum number of results to return. This can be
            used instead of `LIMIT` and is also faster.


        Example of sorting by `foo` ascending and `bar` descending:

        ```
        sort_by(Asc("@foo"), Desc("@bar"))
        ```

        Return the top 10 customers:

        ```
        AggregateRequest()            .group_by("@customer", r.sum("@paid").alias(FIELDNAME))            .sort_by(Desc("@paid"), max=10)
        ```
        SORTBYmaxr   MAX)
rH   r,   r0   r)   r(   r   rI   rB   getr7   )r   rA   kwargsfields_argsfrJ   rV   r   r   r   sort_by   s   
zAggregateRequest.sort_byexpressionsc                 C   s.   t |tr|g}|D ]
}| jd|g q
| S )z
        Specify filter for post-query results using predicates relating to
        values in the result set.

        ### Parameters

        - **fields**: Fields to group by. This can either be a single string,
            or a list of strings.
        FILTER)rH   r   r7   rB   )r   r]   
expressionr   r   r   filter  s
   

zAggregateRequest.filterc                 C   
   d| _ | S )z|
        If set, the `schema` property will contain a list of `[field, type]`
        entries in the result object.
        T)r;   r   r   r   r   with_schema!  s   zAggregateRequest.with_schemac                 C   ra   )zM
        If set, includes the score as an ordinary field of the row.
        T)r?   r   r   r   r   
add_scores)  s   zAggregateRequest.add_scoresscorerc                 C   
   || _ | S )z
        Use a different scoring function to evaluate document relevance.
        Default is `TFIDF`.

        :param scorer: The scoring function to use
                       (e.g. `TFIDF.DOCNORM` or `BM25`)
        )r@   )r   rd   r   r   r   rd   0  s   zAggregateRequest.scorerc                 C   ra   )NT)r<   r   r   r   r   verbatim;  s   zAggregateRequest.verbatimr           r	   max_idlec                 C   s<   dg}|r|dt |g7 }|r|dt |d g7 }|| _| S )N
WITHCURSORCOUNTMAXIDLEi  )r   r=   )r   r	   rh   r   r   r   r   cursor?  s   zAggregateRequest.cursorc                 C   s   | j g}| jr|d | jr|d | jr|d| jg | jr'|d | jr/|| j7 }| jr=|d |d n| j	rU|d |t
t| j	 || j	 | jrb|dt
| jg || j |S )N
WITHSCHEMAVERBATIMSCORER	ADDSCORESLOADr3   DIALECT)r6   r;   appendr<   r@   rB   r?   r=   r9   r8   r   rI   r>   r7   )r   rJ   r   r   r   r   H  s,   





zAggregateRequest.build_argsdialectc                 C   re   )z
        Add a dialect field to the aggregate command.

        - **dialect** - dialect version to execute the query under
        )r>   )r   rt   r   r   r   rt   k  s   zAggregateRequest.dialect)r3   )r
   r2   )r   rg   )r   r   r   r$   r   r   rC   r   r   r   rL   rQ   r   rT   r\   r`   rb   rc   rd   rf   floatrl   r   rt   r   r   r   r   r2   Z   s,    

.-


	#r2   c                   @   s&   e Zd ZdeddfddZdd ZdS )Cursorcidr
   Nc                 C   s   || _ d| _d| _d S )Nr   )rw   rh   r	   r   rw   r   r   r   r   v  r   zCursor.__init__c                 C   s@   t | jg}| jr|dt | jg7 }| jr|dt | jg7 }|S )Nrk   rj   )r   rw   rh   r	   r   r   r   r   r   {  s   zCursor.build_argsr   r   r   r   r   rv   u  s    rv   c                   @   s,   e Zd ZdeddfddZdefddZdS )AggregateResultrl   r
   Nc                 C   s   || _ || _|| _d S r   )rowsrl   schema)r   rz   rl   r{   r   r   r   r     r   zAggregateResult.__init__c              	   C   s@   | j r| j jnd}d| jj dt| ddt| j d| d	S )N<z at 0xxz Rows=z	, Cursor=>)rl   rw   	__class__r   idrI   rz   rx   r   r   r   __repr__  s   zAggregateResult.__repr__)r   r   r   rv   r   r   r   r   r   r   r   ry     s    ry   N)typingr   r   r   r   redis.commands.search.dialectr   objectr"   r   r   r'   r,   r0   r2   rv   ry   r   r   r   r   <module>   s    +  