mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-11 14:15:40 +08:00
feat(go-api): migrate datasets tags aggregation API to Go (#16181)
### Description Migrates the datasets tags aggregation API `GET /api/v1/datasets/tags/aggregation` from Python to Go. ### Changes - Registered the `GET /api/v1/datasets/tags/aggregation` route. - Implemented `AggregateTags` in datasets `handler` and `service`. - Added handler and service `unit tests`. ### Test Verification - Verified by comparing results between Python (9380) and Go (9384) services. - Tested scenarios: single dataset, multiple datasets, empty parameters, and unauthorized/invalid IDs. - All tests and Go `unit tests` passed.
This commit is contained in:
@@ -592,6 +592,44 @@ func (h *DatasetsHandler) RemoveTags(c *gin.Context) {
|
||||
jsonResponse(c, common.CodeSuccess, true, "success")
|
||||
}
|
||||
|
||||
// AggregateTags handles GET /api/v1/datasets/tags/aggregation.
|
||||
// @Summary Aggregate dataset tags
|
||||
// @Description Aggregate tags across multiple datasets
|
||||
// @Tags datasets
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param dataset_ids query string true "Comma-separated dataset IDs"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /api/v1/datasets/tags/aggregation [get]
|
||||
func (h *DatasetsHandler) AggregateTags(c *gin.Context) {
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
if errorCode != common.CodeSuccess {
|
||||
jsonError(c, errorCode, errorMessage)
|
||||
return
|
||||
}
|
||||
|
||||
rawIDs := strings.Split(c.Query("dataset_ids"), ",")
|
||||
datasetIDs := make([]string, 0, len(rawIDs))
|
||||
|
||||
for _, rawID := range rawIDs {
|
||||
tempID := strings.TrimSpace(rawID)
|
||||
if tempID != "" {
|
||||
datasetIDs = append(datasetIDs, tempID)
|
||||
}
|
||||
}
|
||||
if len(datasetIDs) == 0 {
|
||||
jsonError(c, common.CodeDataError, "Lack of dataset_ids in query parameters")
|
||||
return
|
||||
}
|
||||
|
||||
result, code, err := h.datasetsService.AggregateTags(datasetIDs, user.ID)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
jsonResponse(c, common.CodeSuccess, result, "success")
|
||||
}
|
||||
|
||||
// RunIndex Run an indexing task (graph/raptor/mindmap) for a dataset.
|
||||
func (h *DatasetsHandler) RunIndex(c *gin.Context) {
|
||||
user, errorCode, errorMessage := GetUser(c)
|
||||
|
||||
78
internal/handler/datasets_aggregate_tags_test.go
Normal file
78
internal/handler/datasets_aggregate_tags_test.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"ragflow/internal/common"
|
||||
"ragflow/internal/entity"
|
||||
)
|
||||
|
||||
func newAggregateTagsHandlerRouter(authenticated bool) *gin.Engine {
|
||||
gin.SetMode(gin.TestMode)
|
||||
h := &DatasetsHandler{}
|
||||
r := gin.New()
|
||||
r.GET("/api/v1/datasets/tags/aggregation", func(c *gin.Context) {
|
||||
if authenticated {
|
||||
c.Set("user", &entity.User{ID: "user-1"})
|
||||
}
|
||||
h.AggregateTags(c)
|
||||
})
|
||||
return r
|
||||
}
|
||||
|
||||
func TestDatasetsHandlerAggregateTagsRequiresDatasetIDs(t *testing.T) {
|
||||
r := newAggregateTagsHandlerRouter(true)
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/v1/datasets/tags/aggregation", nil)
|
||||
r.ServeHTTP(resp, req)
|
||||
|
||||
if resp.Code != http.StatusOK {
|
||||
t.Fatalf("status=%d body=%s", resp.Code, resp.Body.String())
|
||||
}
|
||||
|
||||
var body struct {
|
||||
Code int `json:"code"`
|
||||
Data interface{} `json:"data"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
if err := json.Unmarshal(resp.Body.Bytes(), &body); err != nil {
|
||||
t.Fatalf("unmarshal response: %v body=%s", err, resp.Body.String())
|
||||
}
|
||||
if body.Code != int(common.CodeDataError) {
|
||||
t.Fatalf("code=%d want=%d body=%s", body.Code, common.CodeDataError, resp.Body.String())
|
||||
}
|
||||
if body.Message != "Lack of dataset_ids in query parameters" {
|
||||
t.Fatalf("message=%q want=%q", body.Message, "Lack of dataset_ids in query parameters")
|
||||
}
|
||||
if body.Data != nil {
|
||||
t.Fatalf("data=%v want nil", body.Data)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDatasetsHandlerAggregateTagsRequiresAuth(t *testing.T) {
|
||||
r := newAggregateTagsHandlerRouter(false)
|
||||
|
||||
resp := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/v1/datasets/tags/aggregation?dataset_ids=123e4567-e89b-12d3-a456-426614174000", nil)
|
||||
r.ServeHTTP(resp, req)
|
||||
|
||||
var body struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
if err := json.Unmarshal(resp.Body.Bytes(), &body); err != nil {
|
||||
t.Fatalf("unmarshal response: %v body=%s", err, resp.Body.String())
|
||||
}
|
||||
if body.Code != int(common.CodeUnauthorized) {
|
||||
t.Fatalf("code=%d want=%d body=%s", body.Code, common.CodeUnauthorized, resp.Body.String())
|
||||
}
|
||||
if body.Message != "User not found" {
|
||||
t.Fatalf("message=%q want=%q", body.Message, "User not found")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user