| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | import datetime | 
					
						
							|  |  |  | import logging | 
					
						
							|  |  |  | import time | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import click | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  | from celery import shared_task  # type: ignore | 
					
						
							| 
									
										
										
										
											2024-02-06 13:21:13 +08:00
										 |  |  | from werkzeug.exceptions import NotFound | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-25 19:49:07 +08:00
										 |  |  | from core.rag.index_processor.constant.index_type import IndexType | 
					
						
							| 
									
										
										
										
											2024-02-22 23:31:57 +08:00
										 |  |  | from core.rag.index_processor.index_processor_factory import IndexProcessorFactory | 
					
						
							| 
									
										
										
										
											2024-12-25 19:49:07 +08:00
										 |  |  | from core.rag.models.document import ChildDocument, Document | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | from extensions.ext_database import db | 
					
						
							|  |  |  | from extensions.ext_redis import redis_client | 
					
						
							| 
									
										
										
										
											2024-12-25 19:49:07 +08:00
										 |  |  | from models.dataset import DatasetAutoDisableLog, DocumentSegment | 
					
						
							| 
									
										
										
										
											2023-06-25 16:49:14 +08:00
										 |  |  | from models.dataset import Document as DatasetDocument | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-26 13:38:37 +08:00
										 |  |  | @shared_task(queue="dataset") | 
					
						
							| 
									
										
										
										
											2023-06-25 16:49:14 +08:00
										 |  |  | def add_document_to_index_task(dataset_document_id: str): | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     Async Add document to index | 
					
						
							| 
									
										
										
										
											2024-11-25 12:02:45 +09:00
										 |  |  |     :param dataset_document_id: | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-25 12:02:45 +09:00
										 |  |  |     Usage: add_document_to_index.delay(dataset_document_id) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-08-26 13:38:37 +08:00
										 |  |  |     logging.info(click.style("Start add document to index: {}".format(dataset_document_id), fg="green")) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     start_at = time.perf_counter() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-25 16:49:14 +08:00
										 |  |  |     dataset_document = db.session.query(DatasetDocument).filter(DatasetDocument.id == dataset_document_id).first() | 
					
						
							|  |  |  |     if not dataset_document: | 
					
						
							| 
									
										
										
										
											2024-08-26 13:38:37 +08:00
										 |  |  |         raise NotFound("Document not found") | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-26 13:38:37 +08:00
										 |  |  |     if dataset_document.indexing_status != "completed": | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-26 13:38:37 +08:00
										 |  |  |     indexing_cache_key = "document_{}_indexing".format(dataset_document.id) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											2024-08-26 13:38:37 +08:00
										 |  |  |         segments = ( | 
					
						
							|  |  |  |             db.session.query(DocumentSegment) | 
					
						
							| 
									
										
										
										
											2024-12-27 17:08:44 +08:00
										 |  |  |             .filter( | 
					
						
							|  |  |  |                 DocumentSegment.document_id == dataset_document.id, | 
					
						
							|  |  |  |                 DocumentSegment.enabled == False, | 
					
						
							|  |  |  |                 DocumentSegment.status == "completed", | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:38:37 +08:00
										 |  |  |             .order_by(DocumentSegment.position.asc()) | 
					
						
							|  |  |  |             .all() | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-25 16:49:14 +08:00
										 |  |  |         documents = [] | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |         for segment in segments: | 
					
						
							| 
									
										
										
										
											2023-06-25 16:49:14 +08:00
										 |  |  |             document = Document( | 
					
						
							|  |  |  |                 page_content=segment.content, | 
					
						
							|  |  |  |                 metadata={ | 
					
						
							|  |  |  |                     "doc_id": segment.index_node_id, | 
					
						
							|  |  |  |                     "doc_hash": segment.index_node_hash, | 
					
						
							|  |  |  |                     "document_id": segment.document_id, | 
					
						
							|  |  |  |                     "dataset_id": segment.dataset_id, | 
					
						
							| 
									
										
										
										
											2024-08-26 13:38:37 +08:00
										 |  |  |                 }, | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-12-25 19:49:07 +08:00
										 |  |  |             if dataset_document.doc_form == IndexType.PARENT_CHILD_INDEX: | 
					
						
							|  |  |  |                 child_chunks = segment.child_chunks | 
					
						
							|  |  |  |                 if child_chunks: | 
					
						
							|  |  |  |                     child_documents = [] | 
					
						
							|  |  |  |                     for child_chunk in child_chunks: | 
					
						
							|  |  |  |                         child_document = ChildDocument( | 
					
						
							|  |  |  |                             page_content=child_chunk.content, | 
					
						
							|  |  |  |                             metadata={ | 
					
						
							|  |  |  |                                 "doc_id": child_chunk.index_node_id, | 
					
						
							|  |  |  |                                 "doc_hash": child_chunk.index_node_hash, | 
					
						
							|  |  |  |                                 "document_id": segment.document_id, | 
					
						
							|  |  |  |                                 "dataset_id": segment.dataset_id, | 
					
						
							|  |  |  |                             }, | 
					
						
							|  |  |  |                         ) | 
					
						
							|  |  |  |                         child_documents.append(child_document) | 
					
						
							|  |  |  |                     document.children = child_documents | 
					
						
							| 
									
										
										
										
											2023-06-25 16:49:14 +08:00
										 |  |  |             documents.append(document) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-25 16:49:14 +08:00
										 |  |  |         dataset = dataset_document.dataset | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if not dataset: | 
					
						
							| 
									
										
										
										
											2024-08-26 13:38:37 +08:00
										 |  |  |             raise Exception("Document has no dataset") | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-22 23:31:57 +08:00
										 |  |  |         index_type = dataset.doc_form | 
					
						
							|  |  |  |         index_processor = IndexProcessorFactory(index_type).init_index_processor() | 
					
						
							|  |  |  |         index_processor.load(dataset, documents) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-25 19:49:07 +08:00
										 |  |  |         # delete auto disable log | 
					
						
							|  |  |  |         db.session.query(DatasetAutoDisableLog).filter( | 
					
						
							|  |  |  |             DatasetAutoDisableLog.document_id == dataset_document.id | 
					
						
							|  |  |  |         ).delete() | 
					
						
							| 
									
										
										
										
											2024-12-27 17:08:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # update segment to enable | 
					
						
							|  |  |  |         db.session.query(DocumentSegment).filter(DocumentSegment.document_id == dataset_document.id).update( | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 DocumentSegment.enabled: True, | 
					
						
							|  |  |  |                 DocumentSegment.disabled_at: None, | 
					
						
							|  |  |  |                 DocumentSegment.disabled_by: None, | 
					
						
							|  |  |  |                 DocumentSegment.updated_at: datetime.datetime.now(datetime.UTC).replace(tzinfo=None), | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-12-25 19:49:07 +08:00
										 |  |  |         db.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |         end_at = time.perf_counter() | 
					
						
							|  |  |  |         logging.info( | 
					
						
							| 
									
										
										
										
											2024-08-26 13:38:37 +08:00
										 |  |  |             click.style( | 
					
						
							|  |  |  |                 "Document added to index: {} latency: {}".format(dataset_document.id, end_at - start_at), fg="green" | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     except Exception as e: | 
					
						
							|  |  |  |         logging.exception("add document to index failed") | 
					
						
							| 
									
										
										
										
											2023-06-25 16:49:14 +08:00
										 |  |  |         dataset_document.enabled = False | 
					
						
							| 
									
										
										
										
											2024-11-24 13:28:46 +08:00
										 |  |  |         dataset_document.disabled_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None) | 
					
						
							| 
									
										
										
										
											2024-08-26 13:38:37 +08:00
										 |  |  |         dataset_document.status = "error" | 
					
						
							| 
									
										
										
										
											2023-06-25 16:49:14 +08:00
										 |  |  |         dataset_document.error = str(e) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |         db.session.commit() | 
					
						
							|  |  |  |     finally: | 
					
						
							|  |  |  |         redis_client.delete(indexing_cache_key) |