o
    ›¨ÊhŠ  ã                   @   s  d dl Z d dlmZ d dlmZ d dlZd dlmZmZm	Z	m
Z
mZ d dlmZmZmZ d dlmZmZmZ d dlmZmZmZmZ d dlmZ d d	lmZmZ d d
lmZ d dl m!Z! z
d dl"m#Z#m$Z$ W n e%yq   edƒ‚w G dd„ deƒZ&G dd„ de	ƒZ'G dd„ deƒZ(dS )é    N)Úsettings)ÚImproperlyConfigured)Ú
BaseEngineÚBaseSearchBackendÚBaseSearchQueryÚEmptyResultsÚ	log_query)Ú	DJANGO_CTÚ	DJANGO_IDÚID)ÚMissingDependencyÚMoreLikeThisErrorÚSkipDocument)ÚCleanÚExactÚ
PythonDataÚRaw)ÚSearchResult)Úget_identifierÚget_model_ct)Úlog)Úhaystack_get_model)ÚSolrÚ	SolrErrorz\The 'solr' backend requires the installation of 'pysolr'. Please refer to the documentation.c                       s¶   e Zd ZdZdZ‡ fdd„Zddd„Zddd	„Zddd„Ze	dd„ ƒZ
	
		
			
	
	
	
	
	
	
	
	
	
	
	
	
d dd„Z	
		
	
	
	
d!dd„Z	
d"dd„Zdd„ Zdd„ Zdd„ Z‡  ZS )#ÚSolrSearchBackend)ÚANDÚNOTÚORÚTO)ú\ú+ú-z&&z||ú!ú(ú)Ú{Ú}ú[ú]ú^ú"ú~Ú*ú?ú:ú/c                    sx   t ƒ j|fi |¤Ž d|vrtd| ƒ‚| dd¡| _| dd¡| _t|d fd| ji| di ¡¤Ž| _t	 
d	¡| _d S )
NÚURLz>You must specify a 'URL' in your settings for connection '%s'.ÚCOLLATE_SPELLINGTÚDATE_FACET_FIELDÚrangeÚtimeoutÚKWARGSÚhaystack)ÚsuperÚ__init__r   ÚgetÚcollateÚdate_facet_fieldr   r4   ÚconnÚloggingÚ	getLoggerr   )ÚselfÚconnection_aliasÚconnection_options©Ú	__class__© úP/var/www/html/env/lib/python3.10/site-packages/haystack/backends/solr_backend.pyr8   :   s"   ÿÿÿþ
ýzSolrSearchBackend.__init__Tc              
   C   sÒ   g }|D ]7}z
|  | |¡¡ W q ty    | j d|¡ Y q ty;   | js*‚ | jjdd|t|ƒdœid� Y qw t	|ƒdkrgz| j
j||| ¡ d� W d S  ttfyf   | js]‚ | j d¡ Y d S w d S )	Nz Indexing for object `%s` skippedz4UnicodeDecodeError while preparing object for updateÚdata)ÚindexÚobject©Úextrar   )ÚcommitÚboostzFailed to add documents to Solr)ÚappendÚfull_preparer   r   ÚdebugÚUnicodeDecodeErrorÚsilently_failÚ	exceptionr   Úlenr<   ÚaddÚget_field_weightsÚIOErrorr   )r?   rG   ÚiterablerK   ÚdocsÚobjrD   rD   rE   ÚupdateO   s.   
þùüýzSolrSearchBackend.updatec              	   C   sZ   t |ƒ}z||dœ}| jjdi |¤Ž W d S  ttfy,   | js"‚ | j d|¡ Y d S w )N)rK   Úidz(Failed to remove document '%s' from SolrrD   )r   r<   ÚdeleterV   r   rQ   r   rR   )r?   Úobj_or_stringrK   Úsolr_idÚkwargsrD   rD   rE   Úremovel   s   

þüzSolrSearchBackend.removeNc              	   C   sØ   |d urt |ttfƒsJ ‚z7|d u r| jjd|d� ng }|D ]}| dtt|ƒf ¡ q| jjd |¡|d� |rB| j 	¡  W d S W d S  t
tfyk   | jsQ‚ |d urb| j dd |¡¡ Y d S | j d¡ Y d S w )Nú*:*)ÚqrK   ú%s:%sú OR z)Failed to clear Solr index of models '%s'ú,zFailed to clear Solr index)Ú
isinstanceÚlistÚtupler<   r\   rM   r	   r   ÚjoinÚoptimizerV   r   rQ   r   rR   )r?   ÚmodelsrK   Úmodels_to_deleteÚmodelrD   rD   rE   Úclear{   s,   þ
þözSolrSearchBackend.clearc              	   K   sš   t |ƒdkrg ddœS | j|fi |¤Ž}z| jj|fi |¤Ž}W n ttfy9   | js-‚ | j d|¡ t	ƒ }Y nw | j
|| d¡| dt¡| d¡d�S )Nr   )ÚresultsÚhitszFailed to query Solr using '%s'Ú	highlightÚresult_classÚdistance_point)rq   rr   rs   )rS   Úbuild_search_kwargsr<   ÚsearchrV   r   rQ   r   rR   r   Ú_process_resultsr9   r   )r?   Úquery_stringr_   Úsearch_kwargsÚraw_resultsrD   rD   rE   ru   š   s"   

û
üzSolrSearchBackend.searchr   Ú Fc           )         sZ  t j| j  ¡ }d|jdœ}|r t|ttfƒrd |¡}||d< |d ur[|dv rM|rM|d j	\}}|d |d< d	||f |d
< |dkrHd|d< nd|d< n| 
d¡rWt d¡ ||d< |d urc||d< |d urm|| |d< ˆ rŠd|d< d|d< tˆ tƒrŠ| ‡ fdd„ˆ  ¡ D ƒ¡ |d u r‘| j}| jdu r¬d|d< t|ƒ ¡ |d< d|d< |r¬||d< |d urØd|d < | ¡ |d!< | ¡ D ]\}}| ¡ D ]\}}| j |¡|d"||f < qÆq¾|d u�rCd|d < | ¡ |d#| j < d$|d%| j < | ¡ D ]M\}}| j | d&¡¡|d'|| jf < | j | d(¡¡|d)|| jf < | d*¡ ¡ }d+| d,¡|f }| d,¡dk�r5|d-7 }d.||f |d/|| jf < qõ|	d u�rUd|d < d0d1„ |	D ƒ|d2< |d u �r`ttd3dƒ}|�rrt|ƒ�rrtd4d5„ |D ƒƒ}n
|�rz|  ¡ }ng }t|ƒd6k�r—|
d u �r‹tƒ }
|
 d7t d8 |¡f ¡ |
d u�r¢t|
ƒ|d9< |�rÃd|d:< | ¡ D ]} | |d;< ||  D ]	}!|!|d<|  < �q·�q­|d u�rõd6d=l!m"}" | #d9g ¡ |"|d> |d? ƒ\\}#}$\}%}&d@|d |#|$|%|&f }'|d9  $|'¡ |d u�r| #d9g ¡ |d j	\}}dA|||d |dB j%f }(|d9  $|(¡ | j&�r#|�r#	 |�r+| |¡ |S )CNz* score)ÚflÚdfú r{   )údistance asczdistance descÚpointÚfieldÚsfieldz%s,%sÚptr~   zgeodist() ascÚsortzgeodist() descz	distance zHIn order to sort by distance, you must call the '.distance(...)' method.ÚstartÚrowsÚtrueÚhlÚ200zhl.fragsizec                    s(   i | ]}|  d ¡r|nd | ˆ | “qS )zhl.)Ú
startswith)Ú.0Úkey©rq   rD   rE   Ú
<dictcomp>ø   s    ÿÿz9SolrSearchBackend.build_search_kwargs.<locals>.<dictcomp>TÚ
spellcheckzspellcheck.collateé   zspellcheck.countzspellcheck.qÚonÚfacetzfacet.fieldzf.%s.facet.%szfacet.%sÚnonezfacet.%s.otherÚ
start_datezf.%s.facet.%s.startÚend_datezf.%s.facet.%s.endÚgap_byz%d%sÚ
gap_amountÚSz+%s/%szf.%s.facet.%s.gapc                 S   s   g | ]
\}}d ||f ‘qS )rc   rD   )rŠ   r€   ÚvaluerD   rD   rE   Ú
<listcomp>.  s    ÿz9SolrSearchBackend.build_search_kwargs.<locals>.<listcomp>zfacet.queryÚ#HAYSTACK_LIMIT_TO_REGISTERED_MODELSc                 s   ó   � | ]}t |ƒV  qd S ©N©r   ©rŠ   rm   rD   rD   rE   Ú	<genexpr>8  ó   € z8SolrSearchBackend.build_search_kwargs.<locals>.<genexpr>r   ú%s:(%s)rd   ÚfqÚstatszstats.fieldzf.%s.stats.facet)Úgenerate_bounding_boxÚpoint_1Úpoint_2z%s:[%s,%s TO %s,%s]z"{!geofilt pt=%s,%s sfield=%s d=%s}Údistance)'r6   Úconnectionsr@   Úget_unified_indexÚdocument_fieldrf   rg   Úsetri   Úcoordsr‰   ÚwarningsÚwarnÚdictrZ   Úkeysr:   Úinclude_spellingÚstrÚlowerÚitemsr<   Ú_from_pythonr;   r9   ÚupperÚgetattrr   rS   ÚsortedÚbuild_models_listrT   r	   Úhaystack.utils.geor¤   Ú
setdefaultrM   ÚkmÚdistance_available))r?   rw   Úsort_byÚstart_offsetÚ
end_offsetÚfieldsrq   ÚfacetsÚdate_facetsÚquery_facetsÚnarrow_queriesÚspelling_queryÚwithinÚdwithinrs   rk   Úlimit_to_registered_modelsrr   r£   r:   Úextra_kwargsrG   r_   ÚlngÚlatÚfacet_fieldÚoptionsr‹   r˜   Úgap_by_stringÚ
gap_stringÚmodel_choicesÚkr‘   r¤   Úmin_latÚmin_lngÚmax_latÚmax_lngÚbboxÚgeofiltrD   rŒ   rE   rt   ±   sö   



ÿ

þÿ

ÿÿ
ÿÿþÿÿ

ÿ
ÿ


ÿ
ÿû
ü
z%SolrSearchBackend.build_search_kwargsc              	   K   s`  ddl m}	 |jj}
|	| j  ¡  |
¡}| ¡ }ddi}|d ur$||d< |d ur,||d< tƒ }|d u r9t	t
ddƒ}|rIt|ƒrItd	d
„ |D ƒƒ}n	|rP|  ¡ }ng }t|ƒdkrk|d u r_tƒ }| dtd |¡f ¡ |rr| |¡ |rzt|ƒ|d< dtt|ƒf }z| jj||fi |¤Ž}W n ttfy¨   | jsœ‚ | j d|¡ tƒ }Y nw | j||d�S )Nr   ©r¨   r{   z*,scorer„   r…   rš   Tc                 s   r›   rœ   r�   rž   rD   rD   rE   rŸ   ¦  r    z3SolrSearchBackend.more_like_this.<locals>.<genexpr>r¡   rd   r¢   rc   z:Failed to fetch More Like This from Solr for document '%s')rr   )r6   r¨   Ú_metaÚconcrete_modelr@   r©   Ú	get_indexÚget_content_fieldr«   r·   r   rS   r¸   r¹   rT   r	   ri   rg   r   r   r<   Úmore_like_thisrV   r   rQ   r   rR   r   rv   )r?   Úmodel_instanceÚadditional_query_stringr¿   rÀ   rk   rÉ   rr   r_   r¨   Úmodel_klassrG   Ú
field_nameÚparamsrÅ   rÑ   Úqueryry   rD   rD   rE   rÞ     sT   ýÿ

ÿ
ù	z SolrSearchBackend.more_like_thisc              	   C   sH  ddl m} g }|j}i }i }	d  }
}|d u rt}t|dƒr%|j di ¡}	t|dƒr›|j di ¡|j di ¡|j di ¡|j d	i ¡d
œ}dD ]&}|| D ]}tt	|| | d d d… || | dd d… ƒƒ|| |< qMqGdD ]*}|| D ]#}tt	|| | d d d d… || | d dd d… ƒƒ|| |< qvqp| j
r×t|dƒr×z|  |¡}W n tyÆ   | jjddd|jiid� | jsÂ‚ d }Y nw |rÕ|d }
t|
tƒsÔJ ‚nd }
|| j  ¡ }| ¡ }|jD ]µ}|t  d¡\}}i }t||ƒ}|�r–||v �r–| |¡}|j}| ¡ D ]5\}}t|ƒ}||v �r|| }||jv �r7t|j| dƒ�r7|j|  |¡||< �q| j  |¡||< �q|t= |t!= |d= |t" t#|di ƒv �r^|j$|t"  |d< |�r�||d< | d¡�r}ddl%m&} |t'|d ƒd�|d< nd |d< ||||t! |d fi |¤Ž}| (|¡ qå|d8 }qå|||	||
|dœS ) Nr   rÙ   r£   Ústats_fieldsrÂ   Úfacet_fieldsÚfacet_datesÚfacet_queriesÚfacet_ranges)rÁ   ÚdatesÚqueriesÚranges)rÁ   é   r�   )rì   ÚcountsrŽ   z)Error extracting spelling suggestions: %srF   rI   éÿÿÿÿÚ.ÚconvertÚscoreÚhighlightingÚhighlightedÚ_point_of_originÚ__dist__)ÚDistance)r¼   Ú	_distance)ro   rp   r£   rÂ   Úspelling_suggestionÚspelling_suggestions))r6   r¨   rp   r   Úhasattrr£   r9   rÂ   rg   Úzipr±   Úextract_spelling_suggestionsÚ	Exceptionr   rR   rŽ   rQ   rf   r²   r@   r©   Úget_indexed_modelsrX   r	   Úsplitr   rÜ   Ú	field_mapr´   rÁ   rñ   r<   Ú
_to_pythonr
   r   r·   ró   Údjango.contrib.gis.measurer÷   ÚfloatrM   )r?   ry   rq   rr   rs   r¨   ro   rp   rÂ   r£   rù   rú   r‹   rÍ   Úunified_indexÚindexed_modelsÚ
raw_resultÚ	app_labelÚ
model_nameÚadditional_fieldsrm   rG   Úindex_field_mapr˜   Ú
string_keyr÷   ÚresultrD   rD   rE   rv   É  sÐ   

üþÿý
þÿý
þ÷




ÿÿ
þÿ
ÿüû
úz"SolrSearchBackend._process_resultsc           	      C   sr  |j  dd ¡}|j  dd ¡}g }|rTt|tƒr/|d }t|tƒr$|g}nt|tƒr.|d g}nt|d tƒr9|}n|dd … }|D ]}| t|tƒrN|d n|¡ qA|S |r·t|tƒr}| ¡ D ]}|d D ]}t|tƒrt| |d ¡ qe| |¡ qeq_|S t|d	 tƒr°t|d tƒr°|D ] }t|tƒr­|d D ]}t|tƒr§| |d ¡ q˜| |¡ q˜q�|S | |d ¡ |S )
NÚ
collationsÚsuggestionsÚ	collationÚcollationQueryr�   rï   Ú
suggestionÚwordr   )rŽ   r9   rf   r¯   r²   rM   Úvalues)	r?   ry   r  r  rú   Úcollation_valuesÚiÚjr  rD   rD   rE   rý   P  sN   



€ÿë

üó

€þz.SolrSearchBackend.extract_spelling_suggestionsc                 C   s<  d}g }|  ¡ D ]‘\}}|jdddddœ}|jdu r|j}|jdv r'd|d	< n;|jd
kr1d|d	< n1|jdkr;d|d	< n'|jdkrEd|d	< n|jdkrOd|d	< n|jdkrYd|d	< n	|jdkrbd|d	< |jrid|d< |jdu rrd|d< |jdu r…d|d< |d	 dkr…d|d	< t|dƒr”|d	 dkr”d|d	< | |¡ q||fS )Nrz   Útext_enr†   Úfalse)râ   ÚtypeÚindexedÚstoredÚmulti_valuedT)ÚdateÚdatetimer  r  ÚintegerÚlongr  ÚbooleanÚngramÚ
edge_ngramÚlocationr  Fr  r  ÚstringÚ	facet_for)	r´   Úindex_fieldnameÚdocumentÚ
field_typeÚis_multivaluedr  r  rû   rM   )r?   rÁ   Úcontent_field_nameÚschema_fieldsÚ_Úfield_classÚ
field_datarD   rD   rE   Úbuild_schemaŒ  sL   û
















zSolrSearchBackend.build_schemac                 K   sD   z| j j|fi |¤ŽW S  ty!   | jjddd|iid� Y dS w )aH  Extract text and metadata from a structured file (PDF, MS Word, etc.)

        Uses the Solr ExtractingRequestHandler, which is based on Apache Tika.
        See the Solr wiki for details:

            http://wiki.apache.org/solr/ExtractingRequestHandler

        Due to the way the ExtractingRequestHandler is implemented it completely
        replaces the normal Haystack indexing process with several unfortunate
        restrictions: only one file per request, the extracted data is added to
        the index with no ability to modify it, etc. To simplify the process and
        allow for more advanced use we'll run using the extract-only mode to
        return the extracted data without adding it to the index so we can then
        use it within Haystack's normal templating process.

        Returns None if metadata cannot be extracted; otherwise returns a
        dictionary containing at least two keys:

            :contents:
                        Extracted full-text content, if applicable
            :metadata:
                        key:value pairs of text strings
        zUnable to extract file contentsrF   ÚfilerI   N)r<   Úextractrþ   r   Úwarning)r?   Úfile_objr_   rD   rD   rE   Úextract_file_contentsÇ  s   
þûz'SolrSearchBackend.extract_file_contents)T)NT)Nr   Nrz   FNNNNNNNNNNNNN)Nr   NNNN)FNN)Ú__name__Ú
__module__Ú__qualname__ÚRESERVED_WORDSÚRESERVED_CHARACTERSr8   rZ   r`   rn   r   ru   rt   rÞ   rv   rý   r1  r6  Ú__classcell__rD   rD   rB   rE   r      sT    




ì R
øK
ÿ <;r   c                   @   sB   e Zd Zdd„ Zdd„ Zddd„Zdd	d
„Zddd„Zdd„ ZdS )ÚSolrSearchQueryc                 C   s   dS )Nra   rD   )r?   rD   rD   rE   Úmatching_all_fragmentë  s   z%SolrSearchQuery.matching_all_fragmentc                 C   sJ  ddl m} d}t|dƒs$t|dƒrt|ƒ}t|tƒr t|ƒ}nt|ƒ}| | ¡}t|t	tt
fƒs8| jj |¡}|dkr?d}nd|| j  ¡  |¡ }dd	d
ddddddddœ
}|jdu r`|}n¤|dv r—|jdkrl|}n˜g }	| d¡D ]}
|	 || | jj |
¡ ¡ qst|	ƒdkr�|	d }nudd |	¡ }nm|dkr»g }|s¢d}nb|D ]}
| d| jj |
¡ ¡ q¤dd |¡ }nI|dkrØ| jj |d ¡}| jj |d ¡}d||f }n,|dkrò|jdkrä|}n t|ƒ | ¡}|| | }n|jdkrþt|ƒ | ¡}|| | }t|ƒ�rt|tƒ�s| d¡�s| d ¡�sd| }d!||f S )"Nr   rÙ   rz   Úinput_type_nameÚvalues_listÚcontentz%s:z%sz*%s*z*%sz%s*z	{%s TO *}z	[%s TO *]z	{* TO %s}z	[* TO %s]z%s~)
rA  ÚcontainsÚendswithr‰   ÚexactÚgtÚgteÚltÚlteÚfuzzyF)rA  rB  r‰   rC  rI  rD  r}   r�   z(%s)z AND Úinz(!*:*)z"%s"rd   r3   z["%s" TO "%s"]r#   r$   z%s%s)r6   r¨   rû   rg   rf   r²   r   r   Úpreparer«   rh   Úbackendr<   rµ   Ú_usingr©   Úget_index_fieldnameÚpost_processr?  r   rM   rS   ri   r   r   r‰   rC  )r?   r€   Úfilter_typer˜   r¨   Ú
query_fragÚprepared_valuer(  Úfilter_typesÚtermsÚpossible_valueÚ
in_optionsr„   ÚendrD   rD   rE   Úbuild_query_fragmentî  sŠ   




ÿ
þö

ÿÿ
ÿ

z$SolrSearchQuery.build_query_fragmentrz   c                 K   sˆ   |r	t |ƒ | ¡}g }t| ¡ ƒD ]&}t|| tƒr,d|| v r,| d||| f ¡ q| d||| f ¡ qd|t d |¡ƒ|f S )Nr}   z%s='%s'z%s=%sz_query_:"{!%s %s}%s")r   rK  r¸   r°   rf   r²   rM   ri   )r?   Úparser_namerw   r_   Ú
kwarg_bitsr‹   rD   rD   rE   Úbuild_alt_parser_queryW  s   ýz&SolrSearchQuery.build_alt_parser_queryNc                 K   sT  | j | jdœ}d }| jr7|d u rg }| jD ]}| d¡r(| d|dd …  ¡ q| d| ¡ qd |¡|d< | jr?| j|d< | jrG| j|d	< | jrO| j|d
< | j	d urY| j	|d< | j
ra| j
|d< | jri| j|d< | jrq| j|d< | jry| j|d< | jr�| j|d< | jr‰| j|d< | jr‘| j|d< |r˜||d< n| jr | j|d< | jr¨| j|d< |S )N)r¿   rr   r!   z%s descr�   z%s ascz, r¾   rÃ   rs   rÈ   rÀ   rÂ   rÁ   rq   rk   rÅ   rÄ   rÇ   rÆ   r£   )r¿   rr   Úorder_byr‰   rM   ri   rÃ   rs   rÈ   rÀ   rÂ   rÁ   rq   rk   rÅ   rÄ   rÇ   rÆ   r£   )r?   rÆ   r_   rx   Úorder_by_listr\  rD   rD   rE   Úbuild_paramsi  sR   þ
















zSolrSearchQuery.build_paramsc                 K   s„   |   ¡ }| j|fi |¤Ž}|r| |¡ | jj|fi |¤Ž}| dg ¡| _| dd¡| _|  |¡| _	| di ¡| _
| dd¡| _dS )ú@Builds and executes the query. Returns a list of search results.ro   rp   r   r£   rù   N)Úbuild_queryr^  rZ   rL  ru   r9   Ú_resultsÚ
_hit_countÚpost_process_facetsÚ_facet_countsÚ_statsÚ_spelling_suggestion)r?   rÆ   r_   Úfinal_queryrx   ro   rD   rD   rE   Úrun§  s   
zSolrSearchQuery.runc                 K   sˆ   | j du s
| jdu rtdƒ‚|  ¡ }| j| j| jdœ}| jdur(| j| j |d< | jj	| j|fi |¤Ž}| 
dg ¡| _| 
dd¡| _dS )	r_  FNz?No instance was provided to determine 'More Like This' results.)r¿   rr   rk   rÀ   ro   rp   r   )Ú_more_like_thisÚ_mlt_instancer   r`  r¿   rr   rk   rÀ   rL  rÞ   r9   ra  rb  )r?   r_   rà   rx   ro   rD   rD   rE   Úrun_mlt·  s$   ÿý
ÿÿzSolrSearchQuery.run_mlt)rz   rœ   )	r7  r8  r9  r>  rX  r[  r^  rh  rk  rD   rD   rD   rE   r=  ê  s    
i

>r=  c                   @   s   e Zd ZeZeZdS )Ú
SolrEngineN)r7  r8  r9  r   rL  r=  rä   rD   rD   rD   rE   rl  Ï  s    rl  ))r­   Údjango.confr   Údjango.core.exceptionsr   r6   Úhaystack.backendsr   r   r   r   r   Úhaystack.constantsr	   r
   r   Úhaystack.exceptionsr   r   r   Úhaystack.inputsr   r   r   r   Úhaystack.modelsr   Úhaystack.utilsr   r   r   r=   Úhaystack.utils.app_loadingr   Úpysolrr   r   ÚImportErrorr   r=  rl  rD   rD   rD   rE   Ú<module>   s8    ÿÿ     Q f