o
    riH                     @   s   d Z ddlmZmZmZmZmZ ddlZddlm	Z	 ddl
mZmZmZmZmZmZ ddlmZ ddlmZ ddlmZ dd	lmZ eeZG d
d deZG dd dZ				dde	dee de de de!defddZ"dS )u   
Milvus 向量存储服务 - 基础版（已废弃）
基于Milvus实现向量存储和检索

.. deprecated:: 2.1
   此实现已废弃，请使用 milvus.py (MilvusVectorStore) 替代
    )ListDictOptionalAnyTupleN)Session)connections
CollectionFieldSchemaCollectionSchemaDataTypeutility)Document)
Embeddings)KnowledgeDocument)get_embedding_factoryc                   @   s\   e Zd ZdZddedee fddZdee	 deee
  fd	d
Zde	dee
 fddZdS )CustomEmbeddingsu<   自定义嵌入类，适配现有的多提供商嵌入服务Ndbmodel_idc                 C   s   || _ || _t | _dS )ux   
        初始化自定义嵌入

        Args:
            db: 数据库会话
            model_id: 模型ID
        N)r   r   r   embedding_factory)selfr   r    r   I/lsinfo/ai/hellotax_ai/base_platform/app/services/storage/milvus_basic.py__init__   s   zCustomEmbeddings.__init__textsreturnc                 C   sH   g }|D ]}| j j|| j| jd}|r|| q|dgd  q|S )u   嵌入文档列表textr   r              )r   generate_embeddingr   r   append)r   r   
embeddingsr   	embeddingr   r   r   embed_documents%   s   z CustomEmbeddings.embed_documentsr   c                 C   s(   | j j|| j| jd}|r|S dgd S )u   嵌入查询文本r   r   r   )r   r    r   r   )r   r   r#   r   r   r   embed_query5   s   zCustomEmbeddings.embed_query)N)__name__
__module____qualname____doc__r   r   intr   r   strfloatr$   r%   r   r   r   r   r      s
    r   c                   @   sV  e Zd ZdZ					d-dedee d	ed
ededefddZ	dedee defddZ
dedee defddZ
dd Zdedeeeef  deee  dedee f
ddZ			d.dee deded ee deeeef  f
d!d"Z			#	d/d$edee deded%ed&edeeeef  fd'd(Zdedefd)d*Zdeeef fd+d,ZdS )0MilvusBasicStoreu.   Milvus 向量存储基础实现（已废弃）Ndocument_vectors	localhost19530Tr   knowledge_base_idcollection_namehostportuse_litec              
   C   s   || _ || _|| _|| _| ||| _z0dt v r t	d n"|r/tj
ddd t	d ntj
d||d t	d| d|  W n tyX } z	td	|   d
}~ww |   d
S )uP  
        初始化Milvus向量存储

        Args:
            db: 数据库会话
            knowledge_base_id: 知识库ID（用于过滤）
            collection_name: 集合名称
            host: Milvus服务器地址
            port: Milvus端口
            use_lite: 是否使用Milvus Lite（本地文件存储）
        defaultu   使用现有的 Milvus 连接z./data/milvus_data.db)aliasuriu*   成功连接到 Milvus Lite (本地存储))r7   r3   r4   u   成功连接到Milvus: :u   连接Milvus失败: N)r   r1   r2   r5   _get_embedding_dimensiondimr   list_connectionsloggerinfoconnect	Exceptionerror_ensure_collection)r   r   r1   r2   r3   r4   r5   er   r   r   r   B   s6   zMilvusBasicStore.__init__r   c              
   C     ze|r[ddl m}m} |||j|k }|r[|jr[|j r3|||jt	|jk }n|||j|jk }|r[|j
r[td|j
 d| d|j d |j
W S td|  W dS  ty } ztd	|  W Y d
}~dS d
}~ww u   
        根据知识库配置获取向量维度

        Args:
            db: 数据库会话
            knowledge_base_id: 知识库ID

        Returns:
            向量维度
        r   )KnowledgeBaseModelzUsing dimension z for knowledge base z	 (model: )z0Using default dimension 2560 for knowledge base i 
  z#Failed to get embedding dimension: N
app.modelsrF   rG   queryfilteridfirstcodeisdigitr*   	dimensionr=   r>   namer@   rA   r   r   r1   rF   rG   kbmodelrC   r   r   r   r:   z   $   

"
"z)MilvusBasicStore._get_embedding_dimensionc              
   C   rD   rE   rI   rS   r   r   r   r:      rV   c              
   C   s  zwt | jrt| j| _td| j  nYtdtj	dddtdtj	dtdtj	dtdtj
d	d
tdtj| jdtdtj
dd
tdtj	dg}t|dd}t| j|d| _ddddid}| jjd|d td| j  | j  W dS  ty } z	td|   d}~ww )u-   确保集合存在，如果不存在则创建u   使用现有集合: rM   T)rR   dtype
is_primaryauto_iddocument_id)rR   rW   chunk_index
chunk_texti  )rR   rW   
max_lengthvector)rR   rW   r;   
model_named   r1   z#Document vectors for knowledge base)fieldsdescription)rR   schemaCOSINEIVF_FLATnlistr   )metric_type
index_typeparams)
field_nameindex_paramsu   创建新集合: u   确保集合存在失败: N)r   has_collectionr2   r	   
collectionr=   r>   r
   r   INT64VARCHARFLOAT_VECTORr;   r   create_indexloadr@   rA   )r   ra   rc   rk   rC   r   r   r   rB      sF   
z#MilvusBasicStore._ensure_collectionrZ   chunksr"   r_   c              
   C   s   z@|gt | dd |D dd |D ||gt | | jpdgt | g}| j|}| j  tdt | d|  |jW S  tyU } z	t	d|   d}~ww )	u7  
        添加文档向量到Milvus

        Args:
            document_id: 文档ID
            chunks: 文档块列表 [{text, metadata, chunk_index}]
            embeddings: 对应的嵌入向量列表
            model_name: 向量模型名称

        Returns:
            插入的向量ID列表
        c                 S      g | ]}|d  qS )r[   r   .0chunkr   r   r   
<listcomp>       z2MilvusBasicStore.add_documents.<locals>.<listcomp>c                 S   rt   r   r   ru   r   r   r   rx      ry   r   u   成功添加 u    个向量到文档 u   添加文档向量失败: N)
lenr1   rm   insertflushr=   r>   primary_keysr@   rA   )r   rZ   rs   r"   r_   entitiesinsert_resultrC   r   r   r   add_documents   s"   

zMilvusBasicStore.add_documents   ffffff?query_embeddingk	thresholdfilter_dictc              
   C   s  zd}| j rd| j  }|r<|r|d7 }| D ]\}}t|tr,|| d| d7 }q|| d| d7 }q|d}ddd	id
}| jj|gd||d |rQ|ndg dd}	g }
|	D ]^}|D ]Q}t|j}||kr| j	
ttj|jdk }|j|jd|jd|jd|jd|r|jnd|r|jndd}|
||f t|
|kr nq`t|
|kr nq\tdt|
 d |
d| W S  ty } z	td|   d}~ww )u  
        相似度搜索

        Args:
            query_embedding: 查询向量
            k: 返回结果数量
            threshold: 相似度阈值 (0-1)
            filter_dict: 过滤条件

        Returns:
            [(结果字典, 相似度分数), ...]
         zknowledge_base_id == z && z == "z" && z == rd   nprobe
   )rg   ri   r^      N)rZ   r[   r\   r_   )data
anns_fieldparamlimitexproutput_fieldsrZ   r[   r\   r_   Unknown)rM   rZ   r[   r   r_   titlecategory_idu   相似度搜索完成，找到 
    个结果u   相似度搜索失败: )r1   items
isinstancer+   rstriprm   searchr,   scorer   rK   r   rL   rM   entitygetrN   r   r   r!   r{   r=   r>   r@   rA   )r   r   r   r   r   r   keyvaluesearch_paramsresultsformatted_resultshitshitr   docdoc_dictrC   r   r   r   similarity_search  sn   








	z"MilvusBasicStore.similarity_search333333?rK   keyword_weightsemantic_weightc              
   C   s  z| j ||d |d d}ddlm} |d}	| j|	||d d}
i }|
D ]}dt|ji||j< q'i }|D ]\}}|d	 }||d
d||< q8| D ]\}}||v r]|d || d< qMg }| D ]*\}}|d }|d dkr{t	|d d dnd
}|| ||  }|
|d |f qd|jdd dd tdt|d|  d |d| W S  ty } z	td|   d}~ww )up  
        混合搜索（关键词 + 语义）

        Args:
            query: 查询文本
            query_embedding: 查询向量
            k: 返回结果数量
            threshold: 相似度阈值
            keyword_weight: 关键词权重
            semantic_weight: 语义权重

        Returns:
            [(结果字典, 综合分数), ...]
        r   g?)r   r   r   r   rz   a  
                SELECT
                    id,
                    title,
                    content,
                    category_id,
                    ts_rank(to_tsvector('simple', content), plainto_tsquery('simple', :query)) as rank
                FROM knowledge_documents
                WHERE to_tsvector('simple', content) @@ plainto_tsquery('simple', :query)
                ORDER BY rank DESC
                LIMIT :k
            )rK   r   r   rZ   r   )r   semantic_scorekeyword_scorer   r   g?g      ?r   c                 S   s   | d S )N   r   )xr   r   r   <lambda>  s    z0MilvusBasicStore.hybrid_search.<locals>.<lambda>T)r   reverseu   混合搜索完成，找到 Nr   u   混合搜索失败: )r   
sqlalchemyr   r   executer,   rankrM   r   minr!   sortr=   r>   r{   r@   rA   )r   rK   r   r   r   r   r   semantic_resultssql_textkeyword_querykeyword_resultkeyword_resultsrowcombined_resultsr   r   doc_idr   final_resultssemantic_normkeyword_normcombined_scorerC   r   r   r   hybrid_searchl  sR   
"zMilvusBasicStore.hybrid_searchc              
   C   sd   zd| }| j | | j   td| d W dS  ty1 } z	td|   d}~ww )u   
        删除文档的所有向量

        Args:
            document_id: 文档ID

        Returns:
            删除的向量数量
        zdocument_id == u   删除文档 u
    的向量r   u   删除文档向量失败: N)rm   deleter}   r=   r>   r@   rA   )r   rZ   r   rC   r   r   r   delete_document_vectors  s   


z(MilvusBasicStore.delete_document_vectorsc              
   C   sX   z| j j}|| jdW S  ty+ } ztd|  d| jdW  Y d}~S d}~ww )u[   
        获取集合统计信息

        Returns:
            统计信息字典
        )total_vectorsr2   u   获取统计信息失败: r   N)rm   num_entitiesr2   r@   r=   rA   )r   statsrC   r   r   r   get_collection_stats  s   z%MilvusBasicStore.get_collection_stats)Nr.   r/   r0   T)r   r   N)r   r   r   r   )r&   r'   r(   r)   r   r   r*   r+   boolr   r:   rB   r   r   r   r,   r   r   r   r   r   r   r   r   r   r   r-   ?   s    
80

.
]
ar-   r/   r0   Tr   r1   r3   r4   r5   r   c                 C   s   t | ||||dS )u$  
    获取Milvus向量存储实例

    Args:
        db: 数据库会话
        knowledge_base_id: 知识库ID
        host: Milvus服务器地址
        port: Milvus端口
        use_lite: 是否使用Milvus Lite（本地文件存储）

    Returns:
        MilvusBasicStore实例
    )r3   r4   r5   )r-   )r   r1   r3   r4   r5   r   r   r   get_vector_store  s   r   )Nr/   r0   T)#r)   typingr   r   r   r   r   loggingsqlalchemy.ormr   pymilvusr   r	   r
   r   r   r   langchain_core.documentsr   LangChainDocumentlangchain_core.embeddingsr   rJ   r   3app.services.llm.backends.embedding_backend_factoryr   	getLoggerr&   r=   r   r-   r*   r+   r   r   r   r   r   r   <module>   s@     
)   =