o
    ›¨ÊhƒC  ã                   @   sú   d dl Z d dlZd dlmZ d dlZd dlmZ d dl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 zd dlZdej  krKd	k sNe‚ e‚d d
lmZmZ W n eyb   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)Ú
BaseEngine)ÚElasticsearchSearchBackendÚElasticsearchSearchQuery)Ú	ALL_FIELDÚDEFAULT_OPERATORÚ	DJANGO_CTÚ	FUZZINESS)ÚMissingDependency)Úget_identifierÚget_model_ct)é   r   r   )é   r   r   )ÚbulkÚscanz³The 'elasticsearch5' backend requires the                             installation of 'elasticsearch>=5.0.0,<6.0.0'.                             Please refer to the documentation.c                       sŒ   e Zd Z‡ fdd„Zddd„Z																	dd
d„Zdd„ Zdd„ Z						ddd„Z						d‡ fdd„	Z	‡  Z
S )ÚElasticsearch5SearchBackendc                    s   t ƒ j|fi |¤Ž d | _d S ©N)ÚsuperÚ__init__Úcontent_field_name)ÚselfÚconnection_aliasÚconnection_options©Ú	__class__© úZ/var/www/html/env/lib/python3.10/site-packages/haystack/backends/elasticsearch5_backend.pyr      s   
z$Elasticsearch5SearchBackend.__init__NTc              	   C   s8  |durt |ttfƒsJ ‚zh|du r(| jjj| jdd� d| _i | _d| _	W dS g }|D ]}| 
dtt|ƒf ¡ q,dddd |¡iii}t| jf|| jd	œ|  ¡ ¤Ž}d
d„ |D ƒ}t| jf|| jdœ|  ¡ ¤Ž | jjj| jd� W dS  tjy›   | js�‚ |dur’| j dd |¡¡ Y dS | j d¡ Y dS w )z´
        Clears the backend of all documents/objects for a collection of models.

        :param models: List or tuple of models to clear.
        :param commit: Not used.
        Ni”  )ÚindexÚignoreFz%s:%sÚqueryÚquery_stringz OR )r   r   c                 s   s   � | ]
}d |d dœV  qdS )ÚdeleteÚ_id)Ú_op_typer"   Nr   )Ú.0Údocr   r   r   Ú	<genexpr>C   s   € 
ÿz4Elasticsearch5SearchBackend.clear.<locals>.<genexpr>)Úactionsr   )r   z2Failed to clear Elasticsearch index of models '%s'ú,z#Failed to clear Elasticsearch index)Ú
isinstanceÚlistÚtupleÚconnÚindicesr!   Ú
index_nameÚsetup_completeÚexisting_mappingr   Úappendr   r   Újoinr   Ú_get_doc_type_optionr   ÚrefreshÚelasticsearchÚTransportErrorÚsilently_failÚlogÚ	exception)r   ÚmodelsÚcommitÚmodels_to_deleteÚmodelr   Ú	generatorr'   r   r   r   Úclear#   sV   ÿÿýüÿÿýü
þöz!Elasticsearch5SearchBackend.clearr   Ú Fc           $      K   s  t j| j  ¡ }|j}|dkrddi ii}ndd|t|ddtdœii}g }|r7t|tt	fƒr3d 
|¡}||d< |d urxg }|D ]4\}}|d	kr_|r_|d
 j\}}d|d ||gd|ddii}n|d	krht d¡ |d|ii}| |¡ q?||d< |rŽd|i ii|d< t|tƒrŽ|d  |¡ | jržd|p•|dtidœi|d< |
d u r¥t	ƒ }
|d uró| di ¡ | ¡ D ]?\}}ddid| |¡idœ}d|v rÐ| d¡|d d< | dd¡rÚd|d< d|v rå| d¡|d< |d  |¡ ||d |< q³|d u�rO| di ¡ | ¡ D ]L\}} |  d¡ ¡ }!|  d d!¡d!k�r'|!d"v�r'd#| d  |!d d!… f }!dd$i||!d%œ|d&||  |  d'¡¡|  |  d(¡¡d)œgd*œiid+œ|d |< �q|	d u�rq| di ¡ |	D ]\}} ddidd| iid,œ|d |< �q\|d u �r|ttd-dƒ}|�rŽt|ƒ�rŽtd.d/„ |D ƒƒ}"n
|�r–|  ¡ }"ng }"t|"ƒd0k�r¨| dt|"ii¡ |
D ]}#| dd|#ii¡ �qª|d u�rÄ| |   |¡¡ |d u�rÑ| |  !|¡¡ |�rýd1d2| d¡ii|d< t|ƒd!k�rñ|d0 |d d1 d3< nd1d2|ii|d d1 d3< |�r| |¡ |S )4Nú*:*r   Ú	match_allr    T)Údefault_fieldÚdefault_operatorr   Úanalyze_wildcardÚauto_generate_phrase_queriesÚ	fuzzinessú Ústored_fieldsÚdistanceÚpointÚ_geo_distanceÚfieldÚorderÚunitÚkmzHIn order to sort by distance, you must call the '.distance(...)' method.ÚsortÚfieldsÚ	highlightÚsuggest)ÚtextÚtermÚaggsÚ_typeÚterms)ÚmetarY   rZ   Úglobal_scopeFÚglobalÚfacet_filterÚgap_byÚ
gap_amounté   )ÚmonthÚyearz%s%sÚdate_histogram)rM   ÚintervalÚ
date_rangeÚ
start_dateÚend_date)ÚfromÚto)rM   Úranges)rZ   rc   rW   )rZ   ÚfilterÚ#HAYSTACK_LIMIT_TO_REGISTERED_MODELSc                 s   ó   � | ]}t |ƒV  qd S r   ©r   ©r$   r=   r   r   r   r&     ó   € zBElasticsearch5SearchBackend.build_search_kwargs.<locals>.<genexpr>r   ÚboolÚmustrk   )"ÚhaystackÚconnectionsr   Úget_unified_indexÚdocument_fieldr   r	   r)   r*   Úsetr2   ÚcoordsÚwarningsÚwarnr1   ÚdictÚupdateÚinclude_spellingr   Ú
setdefaultÚitemsÚget_facet_fieldnameÚpopÚgetÚlowerÚ_from_pythonÚgetattrr   ÚlenÚsortedÚbuild_models_listr   Ú_build_search_query_withinÚ_build_search_query_dwithin)$r   r    Úsort_byÚstart_offsetÚ
end_offsetrR   rS   ÚfacetsÚdate_facetsÚquery_facetsÚnarrow_queriesÚspelling_queryÚwithinÚdwithinÚdistance_pointr:   Úlimit_to_registered_modelsÚresult_classÚextra_kwargsr   Úcontent_fieldÚkwargsÚfiltersÚ
order_listrM   Ú	directionÚlngÚlatÚsort_kwargsÚfacet_fieldnameÚextra_optionsÚfacet_optionsÚvaluerd   Úmodel_choicesÚqr   r   r   Úbuild_search_kwargsZ   sê   úÿÿ
ýÿÿ	
þþÿ
þ
ÿüÿþÿÿý

þ
ÿ



z/Elasticsearch5SearchBackend.build_search_kwargsc                 C   s<   |d j \}}d|d jddœ }dd||d ||dœiiS )	NrK   z%(dist).6f%(unit)srJ   rP   )ÚdistrO   Úgeo_distancerM   ©rŸ   Úlon)rx   rP   )r   r”   rž   rŸ   rJ   r   r   r   rŠ   (  s   þÿz7Elasticsearch5SearchBackend._build_search_query_dwithinc                 C   sL   ddl m} ||d |d ƒ\\}}\}}d|d ||dœ||dœdœiiS )	Nr   )Úgenerate_bounding_boxÚpoint_1Úpoint_2Úgeo_bounding_boxrM   rª   )Útop_leftÚbottom_right)Úhaystack.utils.geor¬   )r   r“   r¬   ÚsouthÚwestÚnorthÚeastr   r   r   r‰   2  s   ÿþÿÿz6Elasticsearch5SearchBackend._build_search_query_withinc                 K   sª  ddl m}	 | js|  ¡  |jj}
|	| j  ¡  |
¡}| 	¡ }i }|d ur)||d< |d ur3|| |d< t
|ƒ}zdd|gd|igdœii}g }|rX|d	krXd
d|ii}| |¡ |d u rbttddƒ}|rrt|ƒrrtdd„ |D ƒƒ}n	|ry|  ¡ }ng }t|ƒdkrŒdt|ii}| |¡ t|ƒdkr£dd|d ddt|ƒiidœii}| jjd|| jddœ|  ¡ ¤|¤Ž}W n tjyÍ   | jsÂ‚ | j d|¡ i }Y nw | j||d�S )Nr   )rt   Úfrom_Úsizer   Úmore_like_thisr"   )rR   ÚlikerA   r    rl   Tc                 s   rm   r   rn   ro   r   r   r   r&   }  rp   z=Elasticsearch5SearchBackend.more_like_this.<locals>.<genexpr>rY   rq   rr   )rr   rk   )Úbodyr   Ú_sourcezCFailed to fetch More Like This from Elasticsearch for document '%s')r—   r   )rs   rt   r/   ÚsetupÚ_metaÚconcrete_modelr   ru   Ú	get_indexÚget_content_fieldr   r1   r…   r   r†   r‡   rˆ   r   r*   r,   Úsearchr.   r3   r5   r6   r7   r8   r9   Ú_process_results)r   Úmodel_instanceÚadditional_query_stringrŒ   r�   r:   r–   r—   rš   rt   Úmodel_klassr   Ú
field_nameÚparamsÚdoc_idÚ	mlt_queryr‘   Úadditional_filterr¥   Úmodel_filterÚraw_resultsr   r   r   r¹   A  s„   ýþÿÿ	
ÿ

þÿÿ	ýü
ûþø
z*Elasticsearch5SearchBackend.more_like_thisc                    sú   t ƒ  |||||¡}i }d|v rwi i i dœ}|d  ¡ D ]Z\}}	|	d d }
|
dkrXdd„ |	d D ƒ|d	 |< d
|	d v rW|	d d
 dkrWt|d	 | dd„ d�}||d	 |< q|
dkrjdd„ |	d D ƒ|d |< q|
dkrv|	d |d |< q||d< |S )NÚaggregations)rR   ÚdatesÚqueriesrZ   rX   rY   c                 S   s   g | ]
}|d  |d f‘qS )ÚkeyÚ	doc_countr   ©r$   Ú
individualr   r   r   Ú
<listcomp>¸  s    ÿÿz@Elasticsearch5SearchBackend._process_results.<locals>.<listcomp>ÚbucketsrR   rN   Úreverse_countc                 S   s   | d S )Nr`   r   )Úxr   r   r   Ú<lambda>¿  s    z>Elasticsearch5SearchBackend._process_results.<locals>.<lambda>)rÑ   rc   c                 S   s(   g | ]}t j  |d  d ¡|d f‘qS )rÑ   iè  rÒ   )ÚdatetimeÚutcfromtimestamprÓ   r   r   r   rÕ   Å  s    û
ÿüÿrÏ   r   rÒ   rÐ   rŽ   )r   rÃ   r   r‡   )r   rÍ   rS   r—   r•   Úgeo_sortÚresultsrŽ   r¡   Ú
facet_infoÚ
facet_typeÚsrtr   r   r   rÃ   ¦  s8   
ÿþÿ€ù	€z,Elasticsearch5SearchBackend._process_results)NT)Nr   Nr@   FNNNNNNNNNNN)Nr   NNNN)FNNF)Ú__name__Ú
__module__Ú__qualname__r   r?   r§   rŠ   r‰   r¹   rÃ   Ú__classcell__r   r   r   r   r      sF    
:
î O

øhúr   c                   @   s   e Zd Zdd„ ZdS )ÚElasticsearch5SearchQueryc                 K   s   |  ¡ | j|< dS )z Adds a regular facet on a field.N)ÚcopyrŽ   )r   rM   Úoptionsr   r   r   Úadd_field_facetÕ  s   z)Elasticsearch5SearchQuery.add_field_facetN)rá   râ   rã   rè   r   r   r   r   rå   Ô  s    rå   c                   @   s   e Zd ZeZeZdS )ÚElasticsearch5SearchEngineN)rá   râ   rã   r   Úbackendrå   r   r   r   r   r   ré   Û  s    ré   )rÚ   ry   Údjango.confr   rs   Úhaystack.backendsr   Ú'haystack.backends.elasticsearch_backendr   r   Úhaystack.constantsr   r   r   r	   Úhaystack.exceptionsr
   Úhaystack.utilsr   r   r5   Ú__version__ÚImportErrorÚelasticsearch.helpersr   r   r   rå   ré   r   r   r   r   Ú<module>   s6    ÿÿÿ   9