| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | import datetime | 
					
						
							|  |  |  | import logging | 
					
						
							|  |  |  | import time | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import click | 
					
						
							|  |  |  | from celery import shared_task | 
					
						
							| 
									
										
										
										
											2023-06-25 16:49:14 +08:00
										 |  |  | from core.index.index import IndexBuilder | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | from extensions.ext_database import db | 
					
						
							|  |  |  | from extensions.ext_redis import redis_client | 
					
						
							| 
									
										
										
										
											2024-01-12 12:34:01 +08:00
										 |  |  | from langchain.schema import Document | 
					
						
							| 
									
										
										
										
											2023-06-25 16:49:14 +08:00
										 |  |  | from models.dataset import Document as DatasetDocument | 
					
						
							| 
									
										
										
										
											2024-01-12 12:34:01 +08:00
										 |  |  | from models.dataset import DocumentSegment | 
					
						
							|  |  |  | from werkzeug.exceptions import NotFound | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-31 13:13:08 +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 | 
					
						
							|  |  |  |     :param document_id: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Usage: add_document_to_index.delay(document_id) | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-06-25 16:49:14 +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: | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |         raise NotFound('Document not found') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-25 16:49:14 +08:00
										 |  |  |     if dataset_document.indexing_status != 'completed': | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-25 16:49:14 +08:00
										 |  |  |     indexing_cache_key = 'document_{}_indexing'.format(dataset_document.id) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         segments = db.session.query(DocumentSegment).filter( | 
					
						
							| 
									
										
										
										
											2023-06-25 16:49:14 +08:00
										 |  |  |             DocumentSegment.document_id == dataset_document.id, | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |             DocumentSegment.enabled == True | 
					
						
							|  |  |  |         ) \ | 
					
						
							|  |  |  |             .order_by(DocumentSegment.position.asc()).all() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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, | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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: | 
					
						
							|  |  |  |             raise Exception('Document has no dataset') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # save vector index | 
					
						
							| 
									
										
										
										
											2023-06-25 16:49:14 +08:00
										 |  |  |         index = IndexBuilder.get_index(dataset, 'high_quality') | 
					
						
							|  |  |  |         if index: | 
					
						
							|  |  |  |             index.add_texts(documents) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # save keyword index | 
					
						
							| 
									
										
										
										
											2023-06-25 16:49:14 +08:00
										 |  |  |         index = IndexBuilder.get_index(dataset, 'economy') | 
					
						
							|  |  |  |         if index: | 
					
						
							|  |  |  |             index.add_texts(documents) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         end_at = time.perf_counter() | 
					
						
							|  |  |  |         logging.info( | 
					
						
							| 
									
										
										
										
											2023-06-25 16:49:14 +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 | 
					
						
							|  |  |  |         dataset_document.disabled_at = datetime.datetime.utcnow() | 
					
						
							|  |  |  |         dataset_document.status = 'error' | 
					
						
							|  |  |  |         dataset_document.error = str(e) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |         db.session.commit() | 
					
						
							|  |  |  |     finally: | 
					
						
							|  |  |  |         redis_client.delete(indexing_cache_key) |