文檔管理
創建完文檔庫之后,您可以按照本文操作上傳文檔。
上傳文檔
本文以通過異步方式上傳本地文檔為例,示例代碼如下:
import time
import io
from typing import Dict, List, Any
from alibabacloud_tea_util import models as util_models
def upload_document_async(
namespace,
namespace_password,
collection,
file_name,
file_path,
metadata: Dict[str, Any] = None,
chunk_overlap: int = None,
chunk_size: int = None,
document_loader_name: str = None,
text_splitter_name: str = None,
dry_run: bool = None,
zh_title_enhance: bool = None,
separators: List[str] = None):
with open(file_path, 'rb') as f:
file_content_bytes = f.read()
request = gpdb_20160503_models.UploadDocumentAsyncAdvanceRequest(
region_id=ADBPG_INSTANCE_REGION,
dbinstance_id=ADBPG_INSTANCE_ID,
namespace=namespace,
namespace_password=namespace_password,
collection=collection,
file_name=file_name,
metadata=metadata,
chunk_overlap=chunk_overlap,
chunk_size=chunk_size,
document_loader_name=document_loader_name,
file_url_object=io.BytesIO(file_content_bytes),
text_splitter_name=text_splitter_name,
dry_run=dry_run,
zh_title_enhance=zh_title_enhance,
separators=separators,
)
response = get_client().upload_document_async_advance(request, util_models.RuntimeOptions())
print(f"upload_document_async response code: {response.status_code}, body:{response.body}")
return response.body.job_id
def wait_upload_document_job(namespace, namespace_password, collection, job_id):
def job_ready():
request = gpdb_20160503_models.GetUploadDocumentJobRequest(
region_id=ADBPG_INSTANCE_REGION,
dbinstance_id=ADBPG_INSTANCE_ID,
namespace=namespace,
namespace_password=namespace_password,
collection=collection,
job_id=job_id,
)
response = get_client().get_upload_document_job(request)
print(f"get_upload_document_job response code: {response.status_code}, body:{response.body}")
return response.body.job.completed
while True:
if job_ready():
print("successfully load document")
break
time.sleep(2)
if __name__ == '__main__':
job_id = upload_document_async("ns1", "Ns1password", "dc1",
"test.pdf", "/root/test.pdf")
wait_upload_document_job("ns1", "Ns1password", "dc1", job_id)
# upload_document_async output:
# {
# "JobId":"95de2856-0cd4-44bb-b216-ea2f0ebcc57b",
# "Message":"Successfully create job",
# "RequestId":"9F870770-C402-19EC-9E26-ED7E4F539C3E",
# "Status":"success"
# }
# get_upload_document_job output:
# {
# "ChunkResult":{
# "ChunkFileUrl":"http://knowledge-base-gp-xx.oss-cn-beijing.aliyuncs.com/ns1/dc1/produce-files/test.pdf/chunks.jsonl?Expires=1706530707&OSSAccessKeyId=ak&Signature=6qUSwBtuthr0L9OxKoTh7kEohxQ%3D",
# "PlainChunkFileUrl":"http://knowledge-base-gp-xx.oss-cn-beijing.aliyuncs.com/ns1/dc1/produce-files/test.pdf/plain_chunks.txt?Expires=1706530707&OSSAccessKeyId=ak&Signature=sxc5iiGUDE2M%2FV0JikFvQE7FdBM%3D"
# },
# "Job":{
# "Completed":true,
# "CreateTime":"2024-01-29 18:15:27.364484",
# "Id":"95de2856-0cd4-44bb-b216-ea2f0ebcc57b",
# "Progress":100,
# "Status":"Success",
# "UpdateTime":"2024-01-29 18:15:53.78808"
# },
# "Message":"Success get job info",
# "RequestId":"64487F02-5A02-1CD9-BA5C-B59E9D3A68CC",
# "Status":"success"
# }
其中upload_document_async的參數說明如下:
namespace:文檔庫所在的Namespace名稱。
namespace_password:Namespace的密碼。
collection:文檔要存入的文檔庫名稱。
file_name:文檔名稱,帶有類型后綴。
file_path:本地的文檔路徑,文件最大200 MB。
metadata:文檔的元數據,需要和創建文檔庫時指定的元數據一致。
chunk_overlap:處理大型數據的切分策略。在分塊處理時,連續的塊之間重疊的數據量,最大值不能超過chunk_size。
chunk_size:處理大型數據的切分策略,數據拆分成較小的部分時每個塊的大小,最大值為2048。
document_loader_name:建議無需指定,會按照文件擴展名自動匹配加載器。自動匹配加載器的詳情,請參見文檔理解。
text_splitter_name:切分器名稱。文檔切分詳情,請參見文檔切分。
dry_run:是否只進行文檔理解和切分,不進行向量化和入庫。取值說明:
true:只進行文檔理解和切分。
false(默認):先進行文檔理解和切分,然后進行向量化和入庫。
zh_title_enhance:是否開啟中文標題加強。取值說明:
true:開啟中文標題加強。
false:關閉中文標題加強。
separators:處理大型數據切分策略的分隔符,一般無需指定。
文檔理解
document_loader_name會根據文檔名后綴來自動決定使用哪個loader:
UnstructuredHTMLLoader:
.html
UnstructuredMarkdownLoader:
.md
PyMuPDFLoader:
.pdf
PyPDFLoader:
.pdf
RapidOCRPDFLoader:
.pdf
JSONLoader:
.json
CSVLoader:
.csv
RapidOCRLoader:
.png
、.jpg
、.jpeg
或.bmp
UnstructuredFileLoader:
.eml
、.msg
、.rst
、.txt
、.xml
、.docx
、.epub
、.odt
、.pptx
或.tsv
當一個文檔類型有多個loader時,如pdf,可以指定其中任一個。若需要識別圖片里的文本,建議使用RapidOCRPDFLoader。
文檔切分
文檔切分的效果由chunk_overlap、chunk_size、text_splitter_name幾部分決定,其中text_splitter_name取值說明如下:
ChineseRecursiveTextSplitter:繼承于RecursiveCharacterTextSplitter,默認以
["\n\n","\n", "。|!|?","\.\s|\!\s|\?\s", ";|;\s", ",|,\s"]
作為分隔符,使用正則匹配,中文比 RecursiveCharacterTextSplitter效果更好一些。SpacyTextSplitter:默認以
["\n\n", "\n", " ", ""]
作為分隔符。可以支持c++
、go
、java
、js
、php
、proto
、python
、rst
、ruby
、rust
、scala
、swift
、markdown
、latex
、html
、sol
、csharp
等多種代碼語言的切分。RecursiveCharacterTextSplitter:默認分隔符為
\n\n
,使用Spacy庫的en_core_web_sm模型來分隔,對全英文文檔支持較好。MarkdownHeaderTextSplitter:針對markdown類型,使用
[ ("#", "head1"), ("##", "head2"), ("###", "head3"), ("####", "head4") ]
來切分。
查看文檔列表
def list_documents(namespace, namespace_password, collection):
request = gpdb_20160503_models.ListDocumentsRequest(
region_id=ADBPG_INSTANCE_REGION,
dbinstance_id=ADBPG_INSTANCE_ID,
namespace=namespace,
namespace_password=namespace_password,
collection=collection,
)
response = get_client().list_documents(request)
print(f"list_documents response code: {response.status_code}, body:{response.body}")
if __name__ == '__main__':
list_documents("ns1", "Ns1password", "dc1")
# output: body:
# {
# "Items":{
# "DocumentList":[
# {
# "FileName":"test.pdf",
# "Source":"OSS"
# }
# ]
# },
# "RequestId":"08D5E2D6-81E1-1D8A-B864-830538B04991",
# "Status":"success"
# }
其中list_documents的參數說明如下:
namespace:文檔庫所在的Namespace名稱。
namespace_password:Namespace的密碼。
collection: 文檔庫名稱。
查看文檔詳情
def describe_document(namespace, namespace_password, collection, file_name):
request = gpdb_20160503_models.DescribeDocumentRequest(
region_id=ADBPG_INSTANCE_REGION,
dbinstance_id=ADBPG_INSTANCE_ID,
namespace=namespace,
namespace_password=namespace_password,
collection=collection,
file_name=file_name
)
response = get_client().describe_document(request)
print(f"describe_document response code: {response.status_code}, body:{response.body}")
if __name__ == '__main__':
describe_document("ns1", "Ns1password", "dc1", "test.pdf")
# output: body:
# {
# "DocsCount":24,
# "DocumentLoader":"PyMuPDFLoader",
# "FileExt":"pdf",
# "FileMd5":"ce16fa68025ebf41649810f0335caf49",
# "FileMtime":"2024-01-29 11:37:27.270611",
# "FileName":"test.pdf",
# "FileSize":8332620,
# "FileVersion":1,
# "RequestId":"D05B4CF1-64F0-1D77-AD9C-C54CAB065571",
# "Source":"OSS",
# "Status":"success",
# "TextSplitter":"ChineseRecursiveTextSplitter"
# }
其中describe_document的參數說明如下:
namespace:文檔庫所在的Namespace名稱。
namespace_password:Namespace的密碼。
collection: 文檔庫名稱。
file_name: 文檔名稱。
返回文檔的詳細信息如下:
DocsCount:文檔被切分的塊數量。
TextSplitter:文檔切分器名稱。
DocumentLoader:文檔Loader名稱。
FileExt:文檔擴展名。
FileMd5:文檔MD5 HASH值。
FileMtime:文檔最新上傳時間。
FileSize:文件大小,單位為字節。
FileVersion:文檔版本,INT類型,代表此文檔被上傳更新了多少次。
刪除文檔
def delete_document(namespace, namespace_password, collection, file_name):
request = gpdb_20160503_models.DeleteDocumentRequest(
region_id=ADBPG_INSTANCE_REGION,
dbinstance_id=ADBPG_INSTANCE_ID,
namespace=namespace,
namespace_password=namespace_password,
collection=collection,
file_name=file_name
)
response = get_client().delete_document(request)
print(f"delete_document response code: {response.status_code}, body:{response.body}")
if __name__ == '__main__':
delete_document("ns1", "Ns1password", "dc1", "test.pdf")
# output: body:
# {
# "Message":"success",
# "RequestId":"DC735368-02DD-48A4-8A26-C8DEB53C5B56",
# "Status":"success"
# }
其中delete_document的參數說明如下:
namespace:文檔庫所在的Namespace名稱。
namespace_password:Namespace的密碼。
collection: 文檔庫名稱。
file_name: 文檔名稱。