mirror of
https://gitee.com/milvus-io/milvus.git
synced 2024-11-30 10:59:32 +08:00
enhance: RESTFUL search api support range search (#29055)
issue: #29004 add a new parameter: `params`, which is a map[string]float64; but now only 2 valid item: radius + range_filter; Signed-off-by: PowderLi <min.li@zilliz.com>
This commit is contained in:
parent
88b4b8b77c
commit
3f7d636ee8
@ -54,5 +54,7 @@ const (
|
||||
ParamRoundDecimal = "round_decimal"
|
||||
ParamOffset = "offset"
|
||||
ParamLimit = "limit"
|
||||
ParamRadius = "radius"
|
||||
ParamRangeFilter = "range_filter"
|
||||
BoundedTimestamp = 2
|
||||
)
|
||||
|
@ -862,6 +862,24 @@ func (h *Handlers) search(c *gin.Context) {
|
||||
params := map[string]interface{}{ // auto generated mapping
|
||||
"level": int(commonpb.ConsistencyLevel_Bounded),
|
||||
}
|
||||
if httpReq.Params != nil {
|
||||
radius, radiusOk := httpReq.Params[ParamRadius]
|
||||
rangeFilter, rangeFilterOk := httpReq.Params[ParamRangeFilter]
|
||||
if rangeFilterOk {
|
||||
if !radiusOk {
|
||||
log.Warn("high level restful api, search params invalid, because only " + ParamRangeFilter)
|
||||
c.AbortWithStatusJSON(http.StatusOK, gin.H{
|
||||
HTTPReturnCode: merr.Code(merr.ErrIncorrectParameterFormat),
|
||||
HTTPReturnMessage: merr.ErrIncorrectParameterFormat.Error() + ", error: invalid search params",
|
||||
})
|
||||
return
|
||||
}
|
||||
params[ParamRangeFilter] = rangeFilter
|
||||
}
|
||||
if radiusOk {
|
||||
params[ParamRadius] = radius
|
||||
}
|
||||
}
|
||||
bs, _ := json.Marshal(params)
|
||||
searchParams := []*commonpb.KeyValuePair{
|
||||
{Key: common.TopKKey, Value: strconv.FormatInt(int64(httpReq.Limit), 10)},
|
||||
|
@ -1294,6 +1294,38 @@ func TestSearch(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
mp := mocks.NewMockProxy(t)
|
||||
mp.EXPECT().Search(mock.Anything, mock.Anything).Return(&milvuspb.SearchResults{
|
||||
Status: &StatusSuccess,
|
||||
Results: &schemapb.SearchResultData{
|
||||
FieldsData: generateFieldData(),
|
||||
Scores: []float32{0.01, 0.04, 0.09},
|
||||
TopK: 3,
|
||||
},
|
||||
}, nil).Once()
|
||||
tt := testCase{
|
||||
name: "search success with params",
|
||||
mp: mp,
|
||||
exceptCode: 200,
|
||||
}
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
testEngine := initHTTPServer(tt.mp, true)
|
||||
rows := []float32{0.0, 0.0}
|
||||
data, _ := json.Marshal(map[string]interface{}{
|
||||
HTTPCollectionName: DefaultCollectionName,
|
||||
"vector": rows,
|
||||
Params: map[string]float64{
|
||||
ParamRadius: 0.9,
|
||||
ParamRangeFilter: 0.1,
|
||||
},
|
||||
})
|
||||
bodyReader := bytes.NewReader(data)
|
||||
req := httptest.NewRequest(http.MethodPost, versional(VectorSearchPath), bodyReader)
|
||||
req.SetBasicAuth(util.UserRoot, util.DefaultRootPassword)
|
||||
w := httptest.NewRecorder()
|
||||
testEngine.ServeHTTP(w, req)
|
||||
assert.Equal(t, tt.exceptCode, w.Code)
|
||||
})
|
||||
}
|
||||
|
||||
type ReturnType int
|
||||
@ -1405,12 +1437,14 @@ func TestHttpRequestFormat(t *testing.T) {
|
||||
merr.ErrMissingRequiredParameters,
|
||||
merr.ErrMissingRequiredParameters,
|
||||
merr.ErrMissingRequiredParameters,
|
||||
merr.ErrIncorrectParameterFormat,
|
||||
}
|
||||
requestJsons := [][]byte{
|
||||
[]byte(`{"collectionName": {"` + DefaultCollectionName + `", "dimension": 2}`),
|
||||
[]byte(`{"collName": "` + DefaultCollectionName + `", "dimension": 2}`),
|
||||
[]byte(`{"collName": "` + DefaultCollectionName + `", "dim": 2}`),
|
||||
[]byte(`{"collectionName": "` + DefaultCollectionName + `"}`),
|
||||
[]byte(`{"collectionName": "` + DefaultCollectionName + `", "vector": [0.0, 0.0], "` + Params + `": {"` + ParamRangeFilter + `": 0.1}}`),
|
||||
}
|
||||
paths := [][]string{
|
||||
{
|
||||
@ -1439,6 +1473,8 @@ func TestHttpRequestFormat(t *testing.T) {
|
||||
versional(VectorInsertPath),
|
||||
versional(VectorUpsertPath),
|
||||
versional(VectorDeletePath),
|
||||
}, {
|
||||
versional(VectorSearchPath),
|
||||
},
|
||||
}
|
||||
for i, pathArr := range paths {
|
||||
|
@ -63,11 +63,12 @@ type SingleUpsertReq struct {
|
||||
}
|
||||
|
||||
type SearchReq struct {
|
||||
DbName string `json:"dbName"`
|
||||
CollectionName string `json:"collectionName" validate:"required"`
|
||||
Filter string `json:"filter"`
|
||||
Limit int32 `json:"limit"`
|
||||
Offset int32 `json:"offset"`
|
||||
OutputFields []string `json:"outputFields"`
|
||||
Vector []float32 `json:"vector"`
|
||||
DbName string `json:"dbName"`
|
||||
CollectionName string `json:"collectionName" validate:"required"`
|
||||
Filter string `json:"filter"`
|
||||
Limit int32 `json:"limit"`
|
||||
Offset int32 `json:"offset"`
|
||||
OutputFields []string `json:"outputFields"`
|
||||
Vector []float32 `json:"vector"`
|
||||
Params map[string]float64 `json:"params"`
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user