mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-29 04:08:12 +08:00
Implement Delete in GO and refactor functions (#13974)
### What problem does this PR solve? Implement Delete in GO and refactor functions ### Type of change - [x] Refactoring <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a remove_chunks command to delete specific or all chunks from a document. * Added new endpoints for chunk removal and chunk update. * **Refactor** * Renamed index commands to dataset/metadata table terminology and updated REST routes accordingly. * Updated chunk update flow to a JSON POST style and improved metadata error messages. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
@@ -254,12 +254,9 @@ func (h *ChunkHandler) List(c *gin.Context) {
|
||||
// @Tags chunks
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param dataset_id path string true "Dataset ID"
|
||||
// @Param document_id path string true "Document ID"
|
||||
// @Param chunk_id path string true "Chunk ID"
|
||||
// @Param request body service.UpdateChunkRequest true "update chunk"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/datasets/{dataset_id}/documents/{document_id}/chunks/{chunk_id} [put]
|
||||
// @Router /v1/chunk/update [post]
|
||||
func (h *ChunkHandler) UpdateChunk(c *gin.Context) {
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
if errorCode != common.CodeSuccess {
|
||||
@@ -267,20 +264,7 @@ func (h *ChunkHandler) UpdateChunk(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Get path parameters
|
||||
datasetID := c.Param("dataset_id")
|
||||
documentID := c.Param("document_id")
|
||||
chunkID := c.Param("chunk_id")
|
||||
|
||||
if datasetID == "" || documentID == "" || chunkID == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": 400,
|
||||
"message": "dataset_id, document_id, and chunk_id are required",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Validate allowed update fields
|
||||
// Validate allowed update fields and get IDs from body
|
||||
var rawBody map[string]interface{}
|
||||
if err := json.NewDecoder(c.Request.Body).Decode(&rawBody); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
@@ -290,7 +274,35 @@ func (h *ChunkHandler) UpdateChunk(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Allowed fields for update
|
||||
// Get required ID fields
|
||||
datasetID, ok := rawBody["dataset_id"].(string)
|
||||
if !ok || datasetID == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": 400,
|
||||
"message": "dataset_id is required",
|
||||
})
|
||||
return
|
||||
}
|
||||
chunkID, ok := rawBody["chunk_id"].(string)
|
||||
if !ok || chunkID == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": 400,
|
||||
"message": "chunk_id is required",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Get document_id from request
|
||||
documentID, ok := rawBody["document_id"].(string)
|
||||
if !ok || documentID == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": 400,
|
||||
"message": "doc_id is required",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Allowed fields for update (exclude ID fields)
|
||||
allowedFields := map[string]bool{
|
||||
"content": true,
|
||||
"important_keywords": true,
|
||||
@@ -301,7 +313,7 @@ func (h *ChunkHandler) UpdateChunk(c *gin.Context) {
|
||||
"tag_feas": true,
|
||||
}
|
||||
for field := range rawBody {
|
||||
if !allowedFields[field] {
|
||||
if field != "dataset_id" && field != "document_id" && field != "chunk_id" && !allowedFields[field] {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": 400,
|
||||
"message": "Update field '" + field + "' is not supported. Updatable fields: content, important_keywords, questions, available, positions, tag_kwd, tag_feas",
|
||||
@@ -366,3 +378,52 @@ func (h *ChunkHandler) UpdateChunk(c *gin.Context) {
|
||||
"message": "chunk updated successfully",
|
||||
})
|
||||
}
|
||||
|
||||
// Remove handles chunk removal requests
|
||||
// @Summary Remove Chunks
|
||||
// @Description Remove chunks from a document
|
||||
// @Tags chunks
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body service.RemoveChunksRequest true "remove chunks request"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/chunk/rm [post]
|
||||
func (h *ChunkHandler) Remove(c *gin.Context) {
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
if errorCode != common.CodeSuccess {
|
||||
jsonError(c, errorCode, errorMessage)
|
||||
return
|
||||
}
|
||||
|
||||
var req service.RemoveChunksRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": 400,
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if req.DocID == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": 400,
|
||||
"message": "doc_id is required",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
deletedCount, err := h.chunkService.RemoveChunks(&req, user.ID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"code": 500,
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 0,
|
||||
"data": deletedCount,
|
||||
"message": "success",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"net/http"
|
||||
"ragflow/internal/common"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
@@ -461,10 +462,18 @@ func (h *DocumentHandler) SetMeta(c *gin.Context) {
|
||||
|
||||
err := h.documentService.SetDocumentMetadata(req.DocID, meta)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"code": 1,
|
||||
"message": "Failed to set metadata: " + err.Error(),
|
||||
})
|
||||
errMsg := err.Error()
|
||||
if strings.Contains(errMsg, "no such document") || strings.Contains(errMsg, "document not found") {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": 1,
|
||||
"message": errMsg,
|
||||
})
|
||||
} else {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"code": 1,
|
||||
"message": "Failed to set metadata: " + errMsg,
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -654,24 +654,24 @@ func (h *KnowledgebaseHandler) GetBasicInfo(c *gin.Context) {
|
||||
jsonResponse(c, common.CodeSuccess, map[string]interface{}{}, "success")
|
||||
}
|
||||
|
||||
// CreateIndex handles the create index request for a knowledge base
|
||||
// @Summary Create Index
|
||||
// @Description Create the Infinity index/table for a knowledge base
|
||||
// CreateDatasetInDocEngine handles the create dataset request for a knowledge base
|
||||
// @Summary Create Dataset in Doc Engine
|
||||
// @Description Create the Infinity table for a knowledge base
|
||||
// @Tags knowledgebase
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param request body service.CreateIndexRequest true "create index request"
|
||||
// @Param request body service.CreateDatasetTableRequest true "create dataset request"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/kb/index [post]
|
||||
func (h *KnowledgebaseHandler) CreateIndex(c *gin.Context) {
|
||||
// @Router /v1/kb/doc_engine_table [post]
|
||||
func (h *KnowledgebaseHandler) CreateDatasetInDocEngine(c *gin.Context) {
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
if errorCode != common.CodeSuccess {
|
||||
jsonError(c, errorCode, errorMessage)
|
||||
return
|
||||
}
|
||||
|
||||
var req service.CreateIndexRequest
|
||||
var req service.CreateDatasetTableRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
jsonError(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
@@ -683,7 +683,7 @@ func (h *KnowledgebaseHandler) CreateIndex(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
result, code, err := h.kbService.CreateIndex(&req)
|
||||
result, code, err := h.kbService.CreateDatasetInDocEngine(&req)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
@@ -692,29 +692,29 @@ func (h *KnowledgebaseHandler) CreateIndex(c *gin.Context) {
|
||||
jsonResponse(c, common.CodeSuccess, result, "success")
|
||||
}
|
||||
|
||||
// DeleteIndexRequest represents the request for deleting an index
|
||||
type DeleteIndexRequest struct {
|
||||
// DeleteDatasetInDocEngineRequest represents the request for deleting a dataset table
|
||||
type DeleteDatasetInDocEngineRequest struct {
|
||||
KBID string `json:"kb_id" binding:"required"`
|
||||
}
|
||||
|
||||
// DeleteIndex handles the delete index request for a knowledge base
|
||||
// @Summary Delete Index
|
||||
// @Description Delete the Infinity index/table for a knowledge base
|
||||
// DeleteDatasetInDocEngine handles the delete dataset request for a knowledge base
|
||||
// @Summary Delete Dataset in Doc Engine
|
||||
// @Description Delete the Infinity table for a knowledge base
|
||||
// @Tags knowledgebase
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param request body DeleteIndexRequest true "delete index request"
|
||||
// @Param request body DeleteDatasetInDocEngineRequest true "delete dataset request"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/kb/index [delete]
|
||||
func (h *KnowledgebaseHandler) DeleteIndex(c *gin.Context) {
|
||||
// @Router /v1/kb/doc_engine_table [delete]
|
||||
func (h *KnowledgebaseHandler) DeleteDatasetInDocEngine(c *gin.Context) {
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
if errorCode != common.CodeSuccess {
|
||||
jsonError(c, errorCode, errorMessage)
|
||||
return
|
||||
}
|
||||
|
||||
var req DeleteIndexRequest
|
||||
var req DeleteDatasetInDocEngineRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
jsonError(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
@@ -726,7 +726,7 @@ func (h *KnowledgebaseHandler) DeleteIndex(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
code, err := h.kbService.DeleteIndex(req.KBID)
|
||||
code, err := h.kbService.DeleteDatasetInDocEngine(req.KBID)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
|
||||
@@ -117,16 +117,16 @@ func (h *TenantHandler) TenantList(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// CreateDocMetaIndex handles the create doc meta index request
|
||||
// @Summary Create Doc Meta Index
|
||||
// @Description Create the document metadata index for a tenant
|
||||
// CreateMetadataInDocEngine handles the create doc meta table request
|
||||
// @Summary Create Doc Meta Table
|
||||
// @Description Create the document metadata table for a tenant
|
||||
// @Tags tenants
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/tenant/doc_meta_index [post]
|
||||
func (h *TenantHandler) CreateDocMetaIndex(c *gin.Context) {
|
||||
// @Router /v1/tenant/doc_engine_metadata_table [post]
|
||||
func (h *TenantHandler) CreateMetadataInDocEngine(c *gin.Context) {
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
if errorCode != common.CodeSuccess {
|
||||
jsonError(c, errorCode, errorMessage)
|
||||
@@ -136,7 +136,7 @@ func (h *TenantHandler) CreateDocMetaIndex(c *gin.Context) {
|
||||
// Use user.ID as tenant ID (user IS the tenant in user mode)
|
||||
tenantID := user.ID
|
||||
|
||||
code, err := h.tenantService.CreateDocMetaIndex(tenantID)
|
||||
code, err := h.tenantService.CreateMetadataInDocEngine(tenantID)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
@@ -149,16 +149,16 @@ func (h *TenantHandler) CreateDocMetaIndex(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteDocMetaIndex handles the delete doc meta index request
|
||||
// @Summary Delete Doc Meta Index
|
||||
// @Description Delete the document metadata index for a tenant
|
||||
// DeleteMetadataInDocEngine handles the delete doc meta table request
|
||||
// @Summary Delete Metadata In Doc Engine
|
||||
// @Description Delete the document metadata table for a tenant
|
||||
// @Tags tenants
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/tenant/doc_meta_index [delete]
|
||||
func (h *TenantHandler) DeleteDocMetaIndex(c *gin.Context) {
|
||||
// @Router /v1/tenant/doc_engine_metadata_table [delete]
|
||||
func (h *TenantHandler) DeleteMetadataInDocEngine(c *gin.Context) {
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
if errorCode != common.CodeSuccess {
|
||||
jsonError(c, errorCode, errorMessage)
|
||||
@@ -168,7 +168,7 @@ func (h *TenantHandler) DeleteDocMetaIndex(c *gin.Context) {
|
||||
// Use user.ID as tenant ID (user IS the tenant in user mode)
|
||||
tenantID := user.ID
|
||||
|
||||
code, err := h.tenantService.DeleteDocMetaIndex(tenantID)
|
||||
code, err := h.tenantService.DeleteMetadataInDocEngine(tenantID)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user