
    =wg<                     h    d dl mZ d dlmZmZmZ d dlmZ d dlm	Z	  G d de	      Z
 G d de	      Zy	)
    )matching)	text_typeuxrange)qcore)WrappingQueryc                   `    e Zd ZdZdefdZd Zd Zd
dZd Z	 G d d	e
j                        Zy)NestedParenta  A query that allows you to search for "nested" documents, where you can
    index (possibly multiple levels of) "parent" and "child" documents using
    the :meth:`~whoosh.writing.IndexWriter.group` and/or
    :meth:`~whoosh.writing.IndexWriter.start_group` methods of a
    :class:`whoosh.writing.IndexWriter` to indicate that hierarchically related
    documents should be kept together::

        schema = fields.Schema(type=fields.ID, text=fields.TEXT(stored=True))

        with ix.writer() as w:
            # Say we're indexing chapters (type=chap) and each chapter has a
            # number of paragraphs (type=p)
            with w.group():
                w.add_document(type="chap", text="Chapter 1")
                w.add_document(type="p", text="Able baker")
                w.add_document(type="p", text="Bright morning")
            with w.group():
                w.add_document(type="chap", text="Chapter 2")
                w.add_document(type="p", text="Car trip")
                w.add_document(type="p", text="Dog eared")
                w.add_document(type="p", text="Every day")
            with w.group():
                w.add_document(type="chap", text="Chapter 3")
                w.add_document(type="p", text="Fine day")

    The ``NestedParent`` query wraps two sub-queries: the "parent query"
    matches a class of "parent documents". The "sub query" matches nested
    documents you want to find. For each "sub document" the "sub query" finds,
    this query acts as if it found the corresponding "parent document".

    >>> with ix.searcher() as s:
    ...   r = s.search(query.Term("text", "day"))
    ...   for hit in r:
    ...     print(hit["text"])
    ...
    Chapter 2
    Chapter 3
    Nc                 <    || _         || _        || _        || _        y)a  
        :param parents: a query, DocIdSet object, or Results object
            representing the documents you want to use as the "parent"
            documents. Where the sub-query matches, the corresponding document
            in these results will be returned as the match.
        :param subq: a query matching the information you want to find.
        :param per_parent_limit: a maximum number of "sub documents" to search
            per parent. The default is None, meaning no limit.
        :param score_fn: a function to use to combine the scores of matching
            sub-documents to calculate the score returned for the parent
            document. The default is ``sum``, that is, add up the scores of the
            sub-documents.
        N)parentschildper_parent_limitscore_fn)selfr   subqr   r   s        J/var/www/horilla/myenv/lib/python3.12/site-packages/whoosh/query/nested.py__init__zNestedParent.__init__J   s!     
 0     c                 .   | j                   }t        |t        j                        r|j	                         }| j
                  j	                         }|t        j                  u s|t        j                  u rt        j                  S | j                  ||      S N)r   
isinstancer   Query	normalizer   	NullQuery	__class__)r   pqs      r   r   zNestedParent.normalize^   sh    LLa%AJJ  "1#7??"~~a##r   c                 6    | j                   j                         S r   )r   requiresr   s    r   r   zNestedParent.requiresi   s    zz""$$r   c                 B   |j                  | j                        }|st        j                  S | j                  j                  ||      }|j                         st        j                  S | j                  ||| j                  |j                         | j                        S r   )_filter_to_combr   r   NullMatcherr   matcher	is_activeNestedParentMatcherr   doc_count_allr   r   searchercontextbitsms        r   r$   zNestedParent.matcherl   s    ''5'''JJx1{{}'''''a1F1F(0(>(>(@(,7 	7r   c              #     K   |j                  | j                        }|sy | j                  j                  ||j	                               }|j                         }|j                         rq|j                         }|j                  |dz         }|j                  |      xs |}t        ||      D ]  }|  |j                  |       |j                         rpy y wN   )r"   r   r   r$   boolean_contextr'   r%   idbeforeafterr   skip_to)	r   r)   r+   r,   maxdocdocnum	parentdoc
nextparentis	            r   deletion_docszNestedParent.deletion_docsx   s     ''5JJx)A)A)CD'')kkmTTVFFQJ/IF+5vJIz2 IIj! kkms   CCCc                   N    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zy) NestedParent.NestedParentMatcherc                     || _         || _        || _        || _        || _        d | _        | j                  j                         r| j                          y y r   )combr   r   r5   r   _nextdocr%   _gather)r   r>   r   r   r5   r   s         r   r   z)NestedParent.NestedParentMatcher.__init__   sK    DIDJ$4D! DK$DM DMzz##% &r   c                     | j                   d uS r   r?   r    s    r   r%   z*NestedParent.NestedParentMatcher.is_active   s    ==,,r   c                      y)NF r    s    r   supports_block_qualityz7NestedParent.NestedParentMatcher.supports_block_quality   s    r   c                 l   | j                   }| j                  }| j                  j                  |j	                         dz         | _        | j                  j                  |j	                               xs | j                  }d}g }|j                         r|j	                         |k  rq|r||kD  r|j                  |       nX|j                  |j                                |j                          |dz  }|j                         r|j	                         |k  rq|r| j                  |      nd}|| _        y )Nr/   r   )r   r   r>   r2   r1   r?   r3   r5   r%   r4   appendscorenextr   
_nextscore)r   r   pplimitr8   countscoresrH   s          r   r@   z(NestedParent.NestedParentMatcher._gather   s    JJE++G !II,,UXXZ!^<DM4CJ EF//#
Z(?uwMM*-ekkm,


 //#
Z(? .4DMM&)E#DOr   c                     | j                   S r   rB   r    s    r   r1   z#NestedParent.NestedParentMatcher.id   s    == r   c                     | j                   S r   )rJ   r    s    r   rH   z&NestedParent.NestedParentMatcher.score       ??"r   c                 X    | j                   j                          | j                          y r   )r   resetr@   r    s    r   rR   z&NestedParent.NestedParentMatcher.reset   s    JJLLNr   c                     | j                   j                         r| j                          y | j                  t        j
                  d | _        y r   )r   r%   r@   r?   r   
ReadTooFarr    s    r   rI   z%NestedParent.NestedParentMatcher.next   s8    zz##%==("---$(DMr   c                 Z    | j                   j                  |       | j                          y r   )r   r4   r@   )r   r1   s     r   r4   z(NestedParent.NestedParentMatcher.skip_to   s    JJr"LLNr   c                 ,    t        | j                        r   NotImplementedErrorr   r    s    r   valuez&NestedParent.NestedParentMatcher.value       %dnn55r   c                     g S r   rD   r    s    r   spansz&NestedParent.NestedParentMatcher.spans       Ir   N)__name__
__module____qualname__r   r%   rE   r@   r1   rH   rR   rI   r4   rY   r\   rD   r   r   r&   r<      s9    			-		$8	!	#		)		6	r   r&   r   )r^   r_   r`   __doc__sumr   r   r   r$   r:   r   Matcherr&   rD   r   r   r
   r
   "   s<    %N 8<c !(	$%
7"Ih.. Ir   r
   c                   J    e Zd ZdZddZddZ G d dej                        Zy)	NestedChildrenai  This is the reverse of a :class:`NestedParent` query: instead of taking
    a query that matches children but returns the parent, this query matches
    parents but returns the children.

    This is useful, for example, to search for an album title and return the
    songs in the album::

        schema = fields.Schema(type=fields.ID(stored=True),
                               album_name=fields.TEXT(stored=True),
                               track_num=fields.NUMERIC(stored=True),
                               track_name=fields.TEXT(stored=True),
                               lyrics=fields.TEXT)
        ix = RamStorage().create_index(schema)

        # Indexing
        with ix.writer() as w:
            # For each album, index a "group" of a parent "album" document and
            # multiple child "track" documents.
            with w.group():
                w.add_document(type="album",
                               artist="The Cure", album_name="Disintegration")
                w.add_document(type="track", track_num=1,
                               track_name="Plainsong")
                w.add_document(type="track", track_num=2,
                               track_name="Pictures of You")
                # ...
            # ...


        # Find songs where the song name has "heaven" in the title and the
        # album the song is on has "hell" in the title
        qp = QueryParser("lyrics", ix.schema)
        with ix.searcher() as s:
            # A query that matches all parents
            all_albums = qp.parse("type:album")

            # A query that matches the parents we want
            albums_with_hell = qp.parse("album_name:hell")

            # A query that matches the desired albums but returns the tracks
            songs_on_hell_albums = NestedChildren(all_albums, albums_with_hell)

            # A query that matches tracks with heaven in the title
            songs_with_heaven = qp.parse("track_name:heaven")

            # A query that finds tracks with heaven in the title on albums
            # with hell in the title
            q = query.And([songs_on_hell_albums, songs_with_heaven])

    c                 .    || _         || _        || _        y r   )r   r   boost)r   r   r   rg   s       r   r   zNestedChildren.__init__  s    

r   Nc                 `   |j                  | j                        }|st        j                  S | j                  j                  ||      }|j                         st        j                  S | j                  |||j                         |j                         j                  | j                        S )Nrg   )r"   r   r   r#   r   r$   r%   NestedChildMatcherr'   reader
is_deletedrg   r(   s        r   r$   zNestedChildren.matcher  s    ''5'''JJx1{{}'''&&tQ0F0F0H'/'8'C'C-1ZZ ' 9 	9r   c                   f    e Zd Z	 ddZd Zd Zd Zd ZddZd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zy)!NestedChildren.NestedChildMatcherc                     || _         || _        || _        || _        || _        d| _        d| _        | j                          y N)parent_combr   limitrl   rg   
_nextchild_nextparent_find_next_children)r   rr   wanted_parent_matcherrs   rl   rg   s         r   r   z*NestedChildren.NestedChildMatcher.__init__  sA    *D.DJDJ(DODJ DO!D$$&r   c                 h    | j                   j                  d| j                  d| j                  dS )N(z, ))r   r^   rr   r   r    s    r   __repr__z*NestedChildren.NestedChildMatcher.__repr__%  s)    #'>>#:#:#'#3#3#'::/ /r   c                 X    | j                   j                          | j                          y r   )r   rR   _resetr    s    r   rR   z'NestedChildren.NestedChildMatcher.reset*  s    JJKKMr   c                 @    d| _         d| _        | j                          y rp   )rt   ru   rv   r    s    r   r}   z(NestedChildren.NestedChildMatcher._reset.  s     DO!D$$&r   c                 4    | j                   | j                  k  S r   )rt   ru   r    s    r   r%   z+NestedChildren.NestedChildMatcher.is_active3  s    ??T%5%555r   c                     | S r   rD   )r   
minqualitys     r   replacez)NestedChildren.NestedChildMatcher.replace6  s    Kr   c                 z   | j                   }| j                  }| j                  }| j                  }| j                  }| j
                  }|j                         rU|j                         dz   }|j                          |j                  |      }||} ||      r|dz  } ||      r||k\  rd	 || _        || _        y r.   )
rr   r   rs   rl   rt   ru   r%   r1   rI   r3   )r   r>   r,   rs   rl   	nextchildr8   s          r   rv   z5NestedChildren.NestedChildMatcher._find_next_children9  s    ##D

AJJEJI))J++-DDFQJ	 "ZZ	2
%!&J !+NI !+
 
* 'DO)Dr   c                     | j                   S r   )rt   r    s    r   r1   z$NestedChildren.NestedChildMatcher.id_  rP   r   c              #      K   | j                         r4| j                          | j                          | j                         r3y y wr   )r%   r1   rI   r    s    r   all_idsz)NestedChildren.NestedChildMatcher.all_idsb  s0     .."ggi		 .."s   AAAc                     | j                   }| j                  }| j                  }| j                  }|dz  }||k  r ||      r|dz  }||k  r	 ||      r|| _        ||k\  ry ||k\  r| j	                          y y r.   )rl   rs   ru   rt   rv   )r   rl   rs   r8   r   s        r   rI   z&NestedChildren.NestedChildMatcher.nextg  s    JJJE))J INI j(Z	-BQ	 j(Z	-B (DO E!j(((* )r   c                 0   | j                   }| j                  }|| j                  k  ry || j                  k  r[| j	                         rJ| j                         |k  r6| j                          | j	                         r| j                         |k  r4y y y y |j	                         r\|j                  |      }|j                  |       |j	                         s| j                  x| _        | _        y | j                          y | j                  x| _        | _        y r   )rr   r   rt   ru   r%   r1   rI   r2   r4   rs   rv   )r   docidr>   wantedpids        r   r4   z)NestedChildren.NestedChildMatcher.skip_to|  s    ##DZZF ' t'''nn&4779u+<IIK nn&4779u+<&+<&!!#kk%(s#'')9=CDOd&6 ,,.59ZZ?$"2r   c                 ,    t        | j                        r   rW   r    s    r   rY   z'NestedChildren.NestedChildMatcher.value  rZ   r   c                     | j                   S r   ri   r    s    r   rH   z'NestedChildren.NestedChildMatcher.score  s    ::r   c                     g S r   rD   r    s    r   r\   z'NestedChildren.NestedChildMatcher.spans  r]   r   Ng      ?)r   )r^   r_   r`   r   r{   rR   r}   r%   r   rv   r1   r   rI   r4   rY   rH   r\   rD   r   r   rj   rn     sM    '*		'	/
		'
	6	$	*L	#	
	+*	@8	6		r   rj   r   r   )	r^   r_   r`   ra   r   r$   r   WrappingMatcherrj   rD   r   r   re   re      s&    1f
9FX55 Fr   re   N)whooshr   whoosh.compatr   r   r   whoosh.queryr   whoosh.query.wrappersr   r
   re   rD   r   r   <module>r      s3   8  . .  /n= nbL] Lr   