mirror of
https://gitee.com/milvus-io/milvus.git
synced 2024-12-02 20:09:57 +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"
|
ParamRoundDecimal = "round_decimal"
|
||||||
ParamOffset = "offset"
|
ParamOffset = "offset"
|
||||||
ParamLimit = "limit"
|
ParamLimit = "limit"
|
||||||
|
ParamRadius = "radius"
|
||||||
|
ParamRangeFilter = "range_filter"
|
||||||
BoundedTimestamp = 2
|
BoundedTimestamp = 2
|
||||||
)
|
)
|
||||||
|
@ -862,6 +862,24 @@ func (h *Handlers) search(c *gin.Context) {
|
|||||||
params := map[string]interface{}{ // auto generated mapping
|
params := map[string]interface{}{ // auto generated mapping
|
||||||
"level": int(commonpb.ConsistencyLevel_Bounded),
|
"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)
|
bs, _ := json.Marshal(params)
|
||||||
searchParams := []*commonpb.KeyValuePair{
|
searchParams := []*commonpb.KeyValuePair{
|
||||||
{Key: common.TopKKey, Value: strconv.FormatInt(int64(httpReq.Limit), 10)},
|
{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
|
type ReturnType int
|
||||||
@ -1405,12 +1437,14 @@ func TestHttpRequestFormat(t *testing.T) {
|
|||||||
merr.ErrMissingRequiredParameters,
|
merr.ErrMissingRequiredParameters,
|
||||||
merr.ErrMissingRequiredParameters,
|
merr.ErrMissingRequiredParameters,
|
||||||
merr.ErrMissingRequiredParameters,
|
merr.ErrMissingRequiredParameters,
|
||||||
|
merr.ErrIncorrectParameterFormat,
|
||||||
}
|
}
|
||||||
requestJsons := [][]byte{
|
requestJsons := [][]byte{
|
||||||
[]byte(`{"collectionName": {"` + DefaultCollectionName + `", "dimension": 2}`),
|
[]byte(`{"collectionName": {"` + DefaultCollectionName + `", "dimension": 2}`),
|
||||||
[]byte(`{"collName": "` + DefaultCollectionName + `", "dimension": 2}`),
|
[]byte(`{"collName": "` + DefaultCollectionName + `", "dimension": 2}`),
|
||||||
[]byte(`{"collName": "` + DefaultCollectionName + `", "dim": 2}`),
|
[]byte(`{"collName": "` + DefaultCollectionName + `", "dim": 2}`),
|
||||||
[]byte(`{"collectionName": "` + DefaultCollectionName + `"}`),
|
[]byte(`{"collectionName": "` + DefaultCollectionName + `"}`),
|
||||||
|
[]byte(`{"collectionName": "` + DefaultCollectionName + `", "vector": [0.0, 0.0], "` + Params + `": {"` + ParamRangeFilter + `": 0.1}}`),
|
||||||
}
|
}
|
||||||
paths := [][]string{
|
paths := [][]string{
|
||||||
{
|
{
|
||||||
@ -1439,6 +1473,8 @@ func TestHttpRequestFormat(t *testing.T) {
|
|||||||
versional(VectorInsertPath),
|
versional(VectorInsertPath),
|
||||||
versional(VectorUpsertPath),
|
versional(VectorUpsertPath),
|
||||||
versional(VectorDeletePath),
|
versional(VectorDeletePath),
|
||||||
|
}, {
|
||||||
|
versional(VectorSearchPath),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i, pathArr := range paths {
|
for i, pathArr := range paths {
|
||||||
|
@ -63,11 +63,12 @@ type SingleUpsertReq struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SearchReq struct {
|
type SearchReq struct {
|
||||||
DbName string `json:"dbName"`
|
DbName string `json:"dbName"`
|
||||||
CollectionName string `json:"collectionName" validate:"required"`
|
CollectionName string `json:"collectionName" validate:"required"`
|
||||||
Filter string `json:"filter"`
|
Filter string `json:"filter"`
|
||||||
Limit int32 `json:"limit"`
|
Limit int32 `json:"limit"`
|
||||||
Offset int32 `json:"offset"`
|
Offset int32 `json:"offset"`
|
||||||
OutputFields []string `json:"outputFields"`
|
OutputFields []string `json:"outputFields"`
|
||||||
Vector []float32 `json:"vector"`
|
Vector []float32 `json:"vector"`
|
||||||
|
Params map[string]float64 `json:"params"`
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user