Feat: add delete all support for delete operations (#13530)

### What problem does this PR solve?

Add delete all support for delete operations.

### Type of change

- [x] New Feature (non-breaking change which adds functionality)
- [x] Documentation Update

---------

Co-authored-by: writinwaters <cai.keith@gmail.com>
This commit is contained in:
Yongteng Lei
2026-03-12 09:47:42 +08:00
committed by GitHub
parent d201a81db7
commit e1b632a7bb
19 changed files with 1042 additions and 975 deletions

View File

@ -235,19 +235,37 @@ async def switch():
@manager.route('/rm', methods=['POST']) # noqa: F821
@login_required
@validate_request("chunk_ids", "doc_id")
@validate_request("doc_id")
async def rm():
req = await get_request_json()
try:
def _rm_sync():
deleted_chunk_ids = req["chunk_ids"]
deleted_chunk_ids = req.get("chunk_ids")
if isinstance(deleted_chunk_ids, list):
unique_chunk_ids = list(dict.fromkeys(deleted_chunk_ids))
has_ids = len(unique_chunk_ids) > 0
else:
elif deleted_chunk_ids is not None:
unique_chunk_ids = [deleted_chunk_ids]
has_ids = deleted_chunk_ids not in (None, "")
else:
unique_chunk_ids = []
has_ids = False
if not has_ids:
if req.get("delete_all") is True:
e, doc = DocumentService.get_by_id(req["doc_id"])
if not e:
return get_data_error_result(message="Document not found!")
tenant_id = DocumentService.get_tenant_id(req["doc_id"])
# Clean up storage assets while index rows still exist for discovery
DocumentService.delete_chunk_images(doc, tenant_id)
condition = {"doc_id": req["doc_id"]}
try:
deleted_count = settings.docStoreConn.delete(condition, search.index_name(tenant_id), doc.kb_id)
except Exception:
return get_data_error_result(message="Chunk deleting failure")
if deleted_count > 0:
DocumentService.decrement_chunk_num(doc.id, doc.kb_id, 1, deleted_count, 0)
return get_json_result(data=True)
return get_json_result(data=True)
e, doc = DocumentService.get_by_id(req["doc_id"])

View File

@ -239,7 +239,12 @@ async def delete_chats(tenant_id):
ids = req.get("ids")
if not ids:
return get_result()
if req.get("delete_all") is True:
ids = [d.id for d in DialogService.query(tenant_id=tenant_id, status=StatusEnum.VALID.value)]
if not ids:
return get_result()
else:
return get_result()
id_list = ids

View File

@ -198,7 +198,13 @@ async def delete(tenant_id):
type: string
description: |
List of dataset IDs to delete.
If `null` or an empty array is provided, no datasets will be deleted.
If `null` or an empty array is provided, no datasets will be deleted
unless `delete_all` is set to `true`.
delete_all:
type: boolean
description: |
If `true` and `ids` is null or empty, delete all datasets owned by the current user.
Defaults to `false`.
responses:
200:
description: Successful operation.
@ -212,7 +218,12 @@ async def delete(tenant_id):
try:
kb_id_instance_pairs = []
if req["ids"] is None or len(req["ids"]) == 0:
return get_result()
if req.get("delete_all"):
req["ids"] = [kb.id for kb in KnowledgebaseService.query(tenant_id=tenant_id)]
if not req["ids"]:
return get_result()
else:
return get_result()
error_kb_ids = []
for kb_id in req["ids"]:

View File

@ -750,7 +750,12 @@ async def delete(tenant_id, dataset_id):
doc_ids = req.get("ids")
if not doc_ids:
return get_result()
if req.get("delete_all") is True:
doc_ids = [doc.id for doc in DocumentService.query(kb_id=dataset_id)]
if not doc_ids:
return get_result()
else:
return get_result()
doc_list = doc_ids
@ -1343,7 +1348,17 @@ async def rm_chunk(tenant_id, dataset_id, document_id):
chunk_ids = req.get("chunk_ids")
if not chunk_ids:
return get_result()
if req.get("delete_all") is True:
doc = docs[0]
# Clean up storage assets while index rows still exist for discovery
DocumentService.delete_chunk_images(doc, tenant_id)
condition = {"doc_id": document_id}
chunk_number = settings.docStoreConn.delete(condition, search.index_name(tenant_id), dataset_id)
if chunk_number != 0:
DocumentService.decrement_chunk_num(document_id, dataset_id, 1, chunk_number, 0)
return get_result(message=f"deleted {chunk_number} chunks")
else:
return get_result()
condition = {"doc_id": document_id}
unique_chunk_ids, duplicate_messages = check_duplicate_ids(chunk_ids, "chunk")

View File

@ -751,7 +751,12 @@ async def delete(tenant_id, chat_id):
ids = req.get("ids")
if not ids:
return get_result()
if req.get("delete_all") is True:
ids = [conv.id for conv in ConversationService.query(dialog_id=chat_id)]
if not ids:
return get_result()
else:
return get_result()
conv_list = ids
@ -799,7 +804,12 @@ async def delete_agent_session(tenant_id, agent_id):
ids = req.get("ids")
if not ids:
return get_result()
if req.get("delete_all") is True:
ids = [conv.id for conv in API4ConversationService.query(dialog_id=agent_id)]
if not ids:
return get_result()
else:
return get_result()
conv_list = ids