o
    ›¨ÊhàO  ã                   @   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)ÚDEFAULT_OPERATORÚ	DJANGO_CTÚ	DJANGO_IDÚ	FUZZINESS)ÚMissingDependency)Úget_identifierÚget_model_ct)é   r   r   )é   r   r   )ÚbulkÚscanz³The 'elasticsearch7' backend requires the                             installation of 'elasticsearch>=7.0.0,<8.0.0'.                             Please refer to the documentation.c                
       sF  e Zd Zdddidddgdœdddgdœd	œd
dddœddddœdœdœdœiZdddœZdddœdddœddiddiddiddiddiddiddidœ	Z‡ fdd „Zd!d"„ Zd#d$„ Zd<d'd(„Z		%	)	%	*	+	%	%	%	%	%	%	%	%	%	%	%d=d,d-„Z
d.d/„ Zd0d1„ Z	%	)	%	%	%	%d>d2d3„Zd4d5„ Z	+	%	%	+d?‡ fd6d7„	Zd8d9„ Zd:d;„ Z‡  ZS )@ÚElasticsearch7SearchBackendr   Úmax_ngram_diffé   ÚstandardÚhaystack_ngramÚ	lowercase)Ú	tokenizerÚfilterÚhaystack_edgengram)Úngram_analyzerÚedgengram_analyzerÚngramé   é   )ÚtypeÚmin_gramÚmax_gramÚ
edge_ngramé   )r   r   )Úanalyzerr   )ÚindexÚanalysisÚtextÚsnowball)r   r$   r   r   r   ÚdateÚ	geo_pointÚbooleanÚfloatÚlong)	r"   r   r)   ÚdatetimeÚlocationr+   r,   r-   Úintegerc                    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/elasticsearch7_backend.pyr3   ]   s   
z$Elasticsearch7SearchBackend.__init__c                 C   s   i S r1   r:   ©r5   r:   r:   r;   Ú_get_doc_type_optiona   s   z0Elasticsearch7SearchBackend._get_doc_type_optionc                 C   s   d|iS )NÚ
propertiesr:   )r5   Úfield_mappingr:   r:   r;   Ú_get_current_mappinge   s   z0Elasticsearch7SearchBackend._get_current_mappingNTc              	   C   s   |durt |ttfƒsJ ‚z\|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|| jd	�}d
d„ |D ƒ}t| j|| jd� | jjj| jd� W dS  tjy�   | jsu‚ |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”  )r%   ÚignoreFz%s:%sÚqueryÚquery_stringz OR )rB   r%   c                 s   s   � | ]
}d |d dœV  qdS )ÚdeleteÚ_id)Ú_op_typerE   Nr:   )Ú.0Údocr:   r:   r;   Ú	<genexpr>ˆ   s   € 
ÿz4Elasticsearch7SearchBackend.clear.<locals>.<genexpr>)Úactionsr%   )r%   z2Failed to clear Elasticsearch index of models '%s'ú,z#Failed to clear Elasticsearch index)Ú
isinstanceÚlistÚtupleÚconnÚindicesrD   Ú
index_nameÚsetup_completeÚexisting_mappingr4   Úappendr   r   Újoinr   r   ÚrefreshÚelasticsearchÚTransportErrorÚsilently_failÚlogÚ	exception)r5   ÚmodelsÚcommitÚmodels_to_deleteÚmodelrB   Ú	generatorrJ   r:   r:   r;   Úcleari   sJ   ÿýÿý
þöz!Elasticsearch7SearchBackend.clearr   Ú Fc           $      K   s  t j| j  ¡ }|j}|dkrddi ii}ndd|t|dtdœii}g }|r6t|tt	fƒr2d 
|¡}||d< |d urwg }|D ]4\}}|d	kr^|r^|d
 j\}}d|d ||gd|ddii}n|d	krgt d¡ |d|ii}| |¡ q>||d< |r�d|i ii|d< t|tƒr�|d  |¡ | jr�d|p”|dd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�rN| 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�rp| 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/d0„ |D ƒƒ}"n
|�r•|  ¡ }"ng }"t|"ƒd1k�r§| dt|"ii¡ |
D ]}#| dd|#ii¡ �q©|d u�rÃ| |  |¡¡ |d u�rÐ| |   |¡¡ |�rüd2d3| d¡ii|d< t|ƒd"k�rð|d1 |d d2 d4< nd2d3|ii|d d2 d4< |�r| |¡ |S )5Nú*:*rB   Ú	match_allrC   T)Údefault_fieldÚdefault_operatorrB   Úanalyze_wildcardÚ	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Úsuggestr'   )r'   ÚtermÚaggsÚ_typeÚterms)Úmetary   rz   Úglobal_scopeFÚglobalÚfacet_filterÚgap_byÚ
gap_amounté   )ÚmonthÚyearz%s%sÚdate_histogram)rn   ÚintervalÚ
date_rangeÚ
start_dateÚend_date)ÚfromÚto)rn   Úranges)rz   rƒ   rw   )rz   r   Ú#HAYSTACK_LIMIT_TO_REGISTERED_MODELSc                 s   ó   � | ]}t |ƒV  qd S r1   ©r   ©rG   r_   r:   r:   r;   rI   J  ó   € zBElasticsearch7SearchBackend.build_search_kwargs.<locals>.<genexpr>r   ÚboolÚmustr   )!ÚhaystackÚconnectionsr6   Úget_unified_indexÚdocument_fieldr   r	   rL   rM   ÚsetrU   ÚcoordsÚwarningsÚwarnrT   ÚdictÚupdateÚinclude_spellingÚ
setdefaultÚitemsÚget_facet_fieldnameÚpopÚgetÚlowerÚ_from_pythonÚgetattrr   ÚlenÚsortedÚbuild_models_listr   Ú_build_search_query_withinÚ_build_search_query_dwithin)$r5   rC   Úsort_byÚstart_offsetÚ
end_offsetrs   rt   Ú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_listrn   Ú	directionÚlngÚlatÚsort_kwargsÚfacet_fieldnameÚextra_optionsÚfacet_optionsÚvaluer„   Úmodel_choicesÚqr:   r:   r;   Úbuild_search_kwargsž   sè   ûÿÿ
ýÿÿ	
þþÿ
þ
ÿüÿþÿÿý

þ
ÿ



z/Elasticsearch7SearchBackend.build_search_kwargsc                 C   s<   |d j \}}d|d jddœ }dd||d ||dœiiS )	Nrl   z%(dist).6f%(unit)srk   rq   )Údistrp   Úgeo_distancern   ©r¾   Úlon)r—   rq   )r5   r³   r½   r¾   rk   r:   r:   r;   r©   k  s   þÿz7Elasticsearch7SearchBackend._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_boxrn   rÉ   )Útop_leftÚbottom_right)Úhaystack.utils.georË   )r5   r²   rË   ÚsouthÚwestÚnorthÚeastr:   r:   r;   r¨   u  s   ÿþÿÿz6Elasticsearch7SearchBackend._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| j|dœgdœii}g }|rZ|d	krZd
d|ii}| |¡ |d u rdttddƒ}|rtt|ƒrttdd„ |D ƒƒ}n	|r{|  ¡ }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   )r“   Úfrom_ÚsizerB   Úmore_like_this)Ú_indexrE   )rs   Úlikerc   rC   r‹   Tc                 s   rŒ   r1   r�   rŽ   r:   r:   r;   rI   Å  r�   z=Elasticsearch7SearchBackend.more_like_this.<locals>.<genexpr>ry   r�   r‘   )r‘   r   )Úbodyr%   Ú_sourcezCFailed to fetch More Like This from Elasticsearch for document '%s')r¶   r:   )r’   r“   rR   ÚsetupÚ_metaÚconcrete_modelr6   r”   Ú	get_indexÚget_content_fieldr   rQ   rT   r¤   r   r¥   r¦   r§   r   rM   rO   ÚsearchrW   rX   rY   rZ   r[   Ú_process_results)r5   Úmodel_instanceÚadditional_query_stringr«   r¬   r\   rµ   r¶   r¹   r“   Úmodel_klassr%   Ú
field_nameÚparamsÚdoc_idÚ	mlt_queryr°   Úadditional_filterrÄ   Úmodel_filterÚraw_resultsr:   r:   r;   rØ   „  s‚   ýþÿþÿÿ
ÿ

þÿÿ	ÿ
ÿþø
z*Elasticsearch7SearchBackend.more_like_thisc                 C   s   |  di ¡  di ¡  dd¡S )NÚhitsÚtotalrÃ   r   )r¡   )r5   rí   r:   r:   r;   Ú_process_hitsê  s   z)Elasticsearch7SearchBackend._process_hitsc                    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)rs   ÚdatesÚqueriesrz   rx   ry   c                 S   s   g | ]
}|d  |d f‘qS )ÚkeyÚ	doc_countr:   ©rG   Ú
individualr:   r:   r;   Ú
<listcomp>ÿ  s    ÿÿz@Elasticsearch7SearchBackend._process_results.<locals>.<listcomp>Úbucketsrs   ro   Úreverse_countc                 S   s   | d S )Nr€   r:   )Úxr:   r:   r;   Ú<lambda>  s    z>Elasticsearch7SearchBackend._process_results.<locals>.<lambda>)rô   rƒ   c                 S   s(   g | ]}t j  |d  d ¡|d f‘qS )rô   iè  rõ   )r.   Úutcfromtimestamprö   r:   r:   r;   rø     s    û
ÿüÿrò   rB   rõ   ró   r­   )r2   rã   rž   r¦   )r5   rí   rt   r¶   r´   Úgeo_sortÚresultsr­   rÀ   Ú
facet_infoÚ
facet_typeÚsrtr8   r:   r;   rã   í  s8   
ÿþÿ€ù	€z,Elasticsearch7SearchBackend._process_resultsc                 C   s   t dditddiiS )Nr   Úkeyword)r   r   r<   r:   r:   r;   Ú_get_common_mapping  s   ÿÿüz/Elasticsearch7SearchBackend._get_common_mappingc                 C   s˜   d}|   ¡ }| ¡ D ]=\}}| j |j| j¡ ¡ }|jdkr#|j|d< |jdu r+|j	}|d dkrB|j
du s;t|dƒrBd	|d< |d
= |||j	< q
||fS )Nrb   g      ð?ÚboostTr   r'   FÚ	facet_forr  r$   )r  rž   ÚFIELD_MAPPINGSr¡   Ú
field_typeÚDEFAULT_FIELD_MAPPINGÚcopyr  ÚdocumentÚindex_fieldnameÚindexedÚhasattr)r5   rs   r4   ÚmappingÚ_Úfield_classr?   r:   r:   r;   Úbuild_schema$  s$   ÿþ


z(Elasticsearch7SearchBackend.build_schema)NT)Nr   Nrb   FNNNNNNNNNNN)Nr   NNNN)FNNF)Ú__name__Ú
__module__Ú__qualname__ÚDEFAULT_SETTINGSr	  r  r3   r=   r@   ra   rÆ   r©   r¨   rØ   rð   rã   r  r  Ú__classcell__r:   r:   r8   r;   r      s¦    ÿþþþþøýýúïüÿ'þþþñ
8
î N

øfú-
r   c                   @   s   e Zd Zdd„ ZdS )ÚElasticsearch7SearchQueryc                 K   s   |  ¡ | j|< d S r1   )r
  r­   )r5   rn   Úoptionsr:   r:   r;   Úadd_field_facet>  s   z)Elasticsearch7SearchQuery.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 )ÚElasticsearch7SearchEngineN)r  r  r  r   Úbackendr  rB   r:   r:   r:   r;   r  B  s    r  )r.   r˜   Údjango.confr   r’   Úhaystack.backendsr   Ú'haystack.backends.elasticsearch_backendr   r   Úhaystack.constantsr   r   r   r	   Úhaystack.exceptionsr
   Úhaystack.utilsr   r   rW   Ú__version__ÚImportErrorÚelasticsearch.helpersr   r   r   r  r  r:   r:   r:   r;   Ú<module>   s8    ÿÿÿ    #