feat: restful support run analyzer(#44803) (#44805)

related: #44803

Signed-off-by: MrPresent-Han <chun.han@gmail.com>
Co-authored-by: MrPresent-Han <chun.han@gmail.com>
This commit is contained in:
Chun Han 2025-10-14 14:41:59 +08:00 committed by GitHub
parent 9e5f9277c0
commit 2ea8d85c2f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 80 additions and 0 deletions

View File

@ -38,6 +38,7 @@ const (
ResourceGroupCategory = "/resource_groups/" ResourceGroupCategory = "/resource_groups/"
SegmentCategory = "/segments/" SegmentCategory = "/segments/"
QuotaCenterCategory = "/quotacenter/" QuotaCenterCategory = "/quotacenter/"
CommonCategory = "/common/"
ListAction = "list" ListAction = "list"
HasAction = "has" HasAction = "has"
@ -77,6 +78,8 @@ const (
AddPrivilegesToGroupAction = "add_privileges_to_group" AddPrivilegesToGroupAction = "add_privileges_to_group"
RemovePrivilegesFromGroupAction = "remove_privileges_from_group" RemovePrivilegesFromGroupAction = "remove_privileges_from_group"
TransferReplicaAction = "transfer_replica" TransferReplicaAction = "transfer_replica"
RunAnalyzerAction = "run_analyzer"
) )
const ( const (

View File

@ -209,6 +209,9 @@ func (h *HandlersV2) RegisterRoutesToV2(router gin.IRouter) {
// segment group // segment group
router.POST(SegmentCategory+DescribeAction, timeoutMiddleware(wrapperPost(func() any { return &GetSegmentsInfoReq{} }, wrapperTraceLog(h.getSegmentsInfo)))) router.POST(SegmentCategory+DescribeAction, timeoutMiddleware(wrapperPost(func() any { return &GetSegmentsInfoReq{} }, wrapperTraceLog(h.getSegmentsInfo))))
router.POST(QuotaCenterCategory+DescribeAction, timeoutMiddleware(wrapperPost(func() any { return &GetQuotaMetricsReq{} }, wrapperTraceLog(h.getQuotaMetrics)))) router.POST(QuotaCenterCategory+DescribeAction, timeoutMiddleware(wrapperPost(func() any { return &GetQuotaMetricsReq{} }, wrapperTraceLog(h.getQuotaMetrics))))
// common
router.POST(CommonCategory+RunAnalyzerAction, timeoutMiddleware(wrapperPost(func() any { return &RunAnalyzerReq{} }, wrapperTraceLog(h.runAnalyzer))))
} }
type ( type (
@ -2847,3 +2850,64 @@ func (h *HandlersV2) getQuotaMetrics(ctx context.Context, c *gin.Context, anyReq
return resp, err return resp, err
} }
func (h *HandlersV2) runAnalyzer(ctx context.Context, c *gin.Context, anyReq any, dbName string) (interface{}, error) {
httpReq := anyReq.(*RunAnalyzerReq)
// Convert text strings to byte slices
placeholder := make([][]byte, len(httpReq.Text))
for i, text := range httpReq.Text {
placeholder[i] = []byte(text)
}
req := &milvuspb.RunAnalyzerRequest{
DbName: dbName,
AnalyzerParams: httpReq.AnalyzerParams,
Placeholder: placeholder,
WithDetail: httpReq.WithDetail,
WithHash: httpReq.WithHash,
CollectionName: httpReq.CollectionName,
FieldName: httpReq.FieldName,
AnalyzerNames: httpReq.AnalyzerNames,
}
c.Set(ContextRequest, req)
resp, err := wrapperProxyWithLimit(ctx, c, req, h.checkAuth, false, "/milvus.proto.milvus.MilvusService/RunAnalyzer", true, h.proxy, func(reqCtx context.Context, req any) (interface{}, error) {
return h.proxy.RunAnalyzer(reqCtx, req.(*milvuspb.RunAnalyzerRequest))
})
if err == nil {
analyzerResp := resp.(*milvuspb.RunAnalyzerResponse)
// Convert response to HTTP-friendly format
results := make([]gin.H, len(analyzerResp.Results))
for i, result := range analyzerResp.Results {
tokens := make([]gin.H, len(result.Tokens))
for j, token := range result.Tokens {
tokenData := gin.H{
"token": token.Token,
}
if httpReq.WithDetail {
tokenData["startOffset"] = token.StartOffset
tokenData["endOffset"] = token.EndOffset
tokenData["position"] = token.Position
tokenData["positionLength"] = token.PositionLength
}
if httpReq.WithHash {
tokenData["hash"] = token.Hash
}
tokens[j] = tokenData
}
results[i] = gin.H{
"tokens": tokens,
}
}
HTTPReturn(c, http.StatusOK, gin.H{
HTTPReturnCode: merr.Code(nil),
HTTPReturnData: gin.H{
"results": results,
},
})
}
return resp, err
}

View File

@ -766,3 +766,16 @@ func (req *GetSegmentsInfoReq) GetSegmentIDs() []int64 {
} }
type GetQuotaMetricsReq struct{} type GetQuotaMetricsReq struct{}
type RunAnalyzerReq struct {
DbName string `json:"dbName"`
AnalyzerParams string `json:"analyzerParams"`
Text []string `json:"text" binding:"required"`
WithDetail bool `json:"withDetail"`
WithHash bool `json:"withHash"`
CollectionName string `json:"collectionName"`
FieldName string `json:"fieldName"`
AnalyzerNames []string `json:"analyzerNames"`
}
func (req *RunAnalyzerReq) GetDbName() string { return req.DbName }