SemanticSearchPOC / adapters /handlers /grpc /v1 /parse_search_request_test.go
KevinStephenson
Adding in weaviate code
b110593
raw
history blame
42.2 kB
// _ _
// __ _____ __ ___ ___ __ _| |_ ___
// \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
// \ V V / __/ (_| |\ V /| | (_| | || __/
// \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
//
// Copyright © 2016 - 2024 Weaviate B.V. All rights reserved.
//
// CONTACT: [email protected]
//
package v1
import (
"testing"
"github.com/weaviate/weaviate/entities/vectorindex/hnsw"
"github.com/weaviate/weaviate/usecases/modulecomponents/additional/generate"
"github.com/weaviate/weaviate/usecases/modulecomponents/additional/rank"
"github.com/weaviate/weaviate/usecases/modulecomponents/nearAudio"
"github.com/weaviate/weaviate/usecases/modulecomponents/nearImage"
"github.com/weaviate/weaviate/usecases/modulecomponents/nearVideo"
"github.com/weaviate/weaviate/entities/schema/crossref"
nearText2 "github.com/weaviate/weaviate/usecases/modulecomponents/nearText"
"github.com/weaviate/weaviate/adapters/handlers/graphql/local/common_filters"
"github.com/weaviate/weaviate/entities/searchparams"
vectorIndex "github.com/weaviate/weaviate/entities/vectorindex/common"
"github.com/stretchr/testify/require"
"github.com/weaviate/weaviate/entities/additional"
"github.com/weaviate/weaviate/entities/dto"
"github.com/weaviate/weaviate/entities/filters"
"github.com/weaviate/weaviate/entities/models"
"github.com/weaviate/weaviate/entities/schema"
"github.com/weaviate/weaviate/entities/search"
pb "github.com/weaviate/weaviate/grpc/generated/protocol/v1"
)
func TestGRPCRequest(t *testing.T) {
classname := "TestClass"
refClass1 := "OtherClass"
refClass2 := "AnotherClass"
dotClass := "DotClass"
objClass := "ObjClass"
defaultTestClassProps := search.SelectProperties{{Name: "name", IsPrimitive: true}, {Name: "number", IsPrimitive: true}, {Name: "floats", IsPrimitive: true}, {Name: "uuid", IsPrimitive: true}}
scheme := schema.Schema{
Objects: &models.Schema{
Classes: []*models.Class{
{
Class: classname,
Properties: []*models.Property{
{Name: "name", DataType: schema.DataTypeText.PropString()},
{Name: "number", DataType: schema.DataTypeInt.PropString()},
{Name: "floats", DataType: schema.DataTypeNumberArray.PropString()},
{Name: "uuid", DataType: schema.DataTypeUUID.PropString()},
{Name: "ref", DataType: []string{refClass1}},
{Name: "multiRef", DataType: []string{refClass1, refClass2}},
},
VectorIndexConfig: hnsw.UserConfig{Distance: vectorIndex.DefaultDistanceMetric},
},
{
Class: refClass1,
Properties: []*models.Property{
{Name: "something", DataType: schema.DataTypeText.PropString()},
{Name: "somethings", DataType: schema.DataTypeTextArray.PropString()},
{Name: "ref2", DataType: []string{refClass2}},
},
VectorIndexConfig: hnsw.UserConfig{Distance: vectorIndex.DefaultDistanceMetric},
},
{
Class: refClass2,
Properties: []*models.Property{
{Name: "else", DataType: schema.DataTypeText.PropString()},
{Name: "ref3", DataType: []string{refClass2}},
},
},
{
Class: dotClass,
Properties: []*models.Property{
{Name: "something", DataType: schema.DataTypeText.PropString()},
},
VectorIndexConfig: hnsw.UserConfig{Distance: vectorIndex.DistanceDot},
},
{
Class: objClass,
Properties: []*models.Property{
{
Name: "something",
DataType: schema.DataTypeObject.PropString(),
NestedProperties: []*models.NestedProperty{
{
Name: "name",
DataType: schema.DataTypeText.PropString(),
},
{
Name: "else",
DataType: schema.DataTypeObject.PropString(),
NestedProperties: []*models.NestedProperty{
{
Name: "name",
DataType: schema.DataTypeText.PropString(),
},
},
},
{
Name: "elses",
DataType: schema.DataTypeObjectArray.PropString(),
NestedProperties: []*models.NestedProperty{
{
Name: "name",
DataType: schema.DataTypeText.PropString(),
},
},
},
},
},
},
VectorIndexConfig: hnsw.UserConfig{Distance: vectorIndex.DefaultDistanceMetric},
},
},
},
}
defaultPagination := &filters.Pagination{Limit: 10}
quorum := pb.ConsistencyLevel_CONSISTENCY_LEVEL_QUORUM
someString1 := "a word"
someString2 := "other"
tests := []struct {
name string
req *pb.SearchRequest
out dto.GetParams
error bool
}{
{
name: "No classname",
req: &pb.SearchRequest{},
out: dto.GetParams{},
error: true,
},
{
name: "No return values given",
req: &pb.SearchRequest{Collection: classname},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination, Properties: defaultTestClassProps,
},
error: false,
},
{
name: "Empty return properties given",
req: &pb.SearchRequest{Collection: classname, Properties: &pb.PropertiesRequest{}},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination, Properties: search.SelectProperties{}, AdditionalProperties: additional.Properties{
NoProps: true,
},
},
error: false,
},
{
name: "Empty return properties given with new default logic",
req: &pb.SearchRequest{Uses_123Api: true, Collection: classname, Properties: &pb.PropertiesRequest{}},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination, Properties: search.SelectProperties{}, AdditionalProperties: additional.Properties{
NoProps: true,
},
},
error: false,
},
{
name: "No return values given for dot distance",
req: &pb.SearchRequest{Collection: dotClass},
out: dto.GetParams{
ClassName: dotClass, Pagination: defaultPagination, Properties: search.SelectProperties{{Name: "something", IsPrimitive: true}},
},
error: false,
},
{
name: "Metadata return values",
req: &pb.SearchRequest{Collection: classname, Metadata: &pb.MetadataRequest{Vector: true, Certainty: false, IsConsistent: true}},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{
Vector: true,
NoProps: false,
IsConsistent: true,
},
},
error: false,
},
{
name: "Metadata ID only query",
req: &pb.SearchRequest{Collection: classname, Properties: &pb.PropertiesRequest{}, Metadata: &pb.MetadataRequest{Uuid: true}},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: search.SelectProperties{},
AdditionalProperties: additional.Properties{
ID: true,
NoProps: true,
},
},
error: false,
},
{
name: "Metadata ID only query using new default logic",
req: &pb.SearchRequest{Uses_123Api: true, Collection: classname, Properties: &pb.PropertiesRequest{}, Metadata: &pb.MetadataRequest{Uuid: true}},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: search.SelectProperties{},
AdditionalProperties: additional.Properties{
ID: true,
NoProps: true,
},
},
error: false,
},
{
name: "Properties return all nonref values",
req: &pb.SearchRequest{Collection: classname},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination, Properties: defaultTestClassProps,
},
error: false,
},
{
name: "Properties return all nonref values with new default logic",
req: &pb.SearchRequest{Uses_123Api: true, Collection: classname, Properties: &pb.PropertiesRequest{ReturnAllNonrefProperties: true}},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination, Properties: defaultTestClassProps,
},
error: false,
},
{
name: "Properties return all nonref values with ref and specific props using new default logic",
req: &pb.SearchRequest{Uses_123Api: true, Collection: classname, Properties: &pb.PropertiesRequest{
ReturnAllNonrefProperties: true,
RefProperties: []*pb.RefPropertiesRequest{{
ReferenceProperty: "ref",
TargetCollection: refClass1,
Metadata: &pb.MetadataRequest{Vector: true, Certainty: false},
Properties: &pb.PropertiesRequest{NonRefProperties: []string{"something"}},
}},
}},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination, Properties: search.SelectProperties{
{Name: "name", IsPrimitive: true},
{Name: "number", IsPrimitive: true},
{Name: "floats", IsPrimitive: true},
{Name: "uuid", IsPrimitive: true},
{Name: "ref", IsPrimitive: false, Refs: []search.SelectClass{
{
ClassName: refClass1,
RefProperties: search.SelectProperties{{Name: "something", IsPrimitive: true}},
AdditionalProperties: additional.Properties{Vector: true},
},
}},
},
},
error: false,
},
{
name: "Properties return all nonref values with ref and all nonref props using new default logic",
req: &pb.SearchRequest{Uses_123Api: true, Collection: classname, Properties: &pb.PropertiesRequest{
ReturnAllNonrefProperties: true,
RefProperties: []*pb.RefPropertiesRequest{{
ReferenceProperty: "ref",
TargetCollection: refClass1,
Metadata: &pb.MetadataRequest{Vector: true, Certainty: false},
Properties: &pb.PropertiesRequest{ReturnAllNonrefProperties: true},
}},
}},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination, Properties: search.SelectProperties{
{Name: "name", IsPrimitive: true},
{Name: "number", IsPrimitive: true},
{Name: "floats", IsPrimitive: true},
{Name: "uuid", IsPrimitive: true},
{Name: "ref", IsPrimitive: false, Refs: []search.SelectClass{
{
ClassName: refClass1,
RefProperties: search.SelectProperties{
{Name: "something", IsPrimitive: true},
{Name: "somethings", IsPrimitive: true},
},
AdditionalProperties: additional.Properties{Vector: true},
},
}},
},
},
error: false,
},
{
name: "Properties return values only ref",
req: &pb.SearchRequest{Collection: classname, Properties: &pb.PropertiesRequest{
RefProperties: []*pb.RefPropertiesRequest{
{
ReferenceProperty: "ref",
TargetCollection: refClass1,
Metadata: &pb.MetadataRequest{Vector: true, Certainty: false},
Properties: &pb.PropertiesRequest{NonRefProperties: []string{"something"}},
},
},
}},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination, Properties: search.SelectProperties{{Name: "ref", IsPrimitive: false, Refs: []search.SelectClass{{ClassName: refClass1, RefProperties: search.SelectProperties{{Name: "something", IsPrimitive: true}}, AdditionalProperties: additional.Properties{
Vector: true,
}}}}},
},
error: false,
},
{
name: "Properties return values only ref using new default logic",
req: &pb.SearchRequest{Uses_123Api: true, Collection: classname, Properties: &pb.PropertiesRequest{
RefProperties: []*pb.RefPropertiesRequest{
{
ReferenceProperty: "ref",
TargetCollection: refClass1,
Metadata: &pb.MetadataRequest{Vector: true, Certainty: false},
Properties: &pb.PropertiesRequest{NonRefProperties: []string{"something"}},
},
},
}},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination, Properties: search.SelectProperties{{Name: "ref", IsPrimitive: false, Refs: []search.SelectClass{{ClassName: refClass1, RefProperties: search.SelectProperties{{Name: "something", IsPrimitive: true}}, AdditionalProperties: additional.Properties{
Vector: true,
}}}}},
},
error: false,
},
{
name: "Properties return values non-ref",
req: &pb.SearchRequest{Collection: classname, Properties: &pb.PropertiesRequest{NonRefProperties: []string{"name", "CapitalizedName"}}},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination, Properties: search.SelectProperties{{Name: "name", IsPrimitive: true}, {Name: "capitalizedName", IsPrimitive: true}},
},
error: false,
},
{
name: "Properties return values non-ref with new default logic",
req: &pb.SearchRequest{Uses_123Api: true, Collection: classname, Properties: &pb.PropertiesRequest{NonRefProperties: []string{"name", "CapitalizedName"}}},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination, Properties: search.SelectProperties{{Name: "name", IsPrimitive: true}, {Name: "capitalizedName", IsPrimitive: true}},
},
error: false,
},
{
name: "ref returns no values given",
req: &pb.SearchRequest{Collection: classname, Properties: &pb.PropertiesRequest{RefProperties: []*pb.RefPropertiesRequest{{ReferenceProperty: "ref", TargetCollection: refClass1}}}},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination, Properties: search.SelectProperties{{Name: "ref", IsPrimitive: false, Refs: []search.SelectClass{{ClassName: refClass1, RefProperties: search.SelectProperties{{Name: "something", IsPrimitive: true}, {Name: "somethings", IsPrimitive: true}}}}}},
},
error: false,
},
{
name: "Properties return values multi-ref (no linked class with error)",
req: &pb.SearchRequest{Collection: classname, Properties: &pb.PropertiesRequest{RefProperties: []*pb.RefPropertiesRequest{{ReferenceProperty: "multiRef", Metadata: &pb.MetadataRequest{Vector: true, Certainty: false}, Properties: &pb.PropertiesRequest{NonRefProperties: []string{"something"}}}}}},
out: dto.GetParams{},
error: true,
},
{
name: "Properties return values multi-ref",
req: &pb.SearchRequest{Collection: classname, Properties: &pb.PropertiesRequest{RefProperties: []*pb.RefPropertiesRequest{
{ReferenceProperty: "multiRef", TargetCollection: refClass1, Metadata: &pb.MetadataRequest{Vector: true, Certainty: false}, Properties: &pb.PropertiesRequest{NonRefProperties: []string{"something"}}},
{ReferenceProperty: "MultiRef", TargetCollection: refClass2, Metadata: &pb.MetadataRequest{Uuid: true}, Properties: &pb.PropertiesRequest{NonRefProperties: []string{"Else"}}},
}}},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination, Properties: search.SelectProperties{
{Name: "multiRef", IsPrimitive: false, Refs: []search.SelectClass{{ClassName: refClass1, RefProperties: search.SelectProperties{{Name: "something", IsPrimitive: true}}, AdditionalProperties: additional.Properties{Vector: true}}}},
{Name: "multiRef", IsPrimitive: false, Refs: []search.SelectClass{{ClassName: refClass2, RefProperties: search.SelectProperties{{Name: "else", IsPrimitive: true}}, AdditionalProperties: additional.Properties{ID: true}}}},
},
},
error: false,
},
{
name: "hybrid ranked",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true, Certainty: false},
HybridSearch: &pb.Hybrid{Query: "query", FusionType: pb.Hybrid_FUSION_TYPE_RANKED, Alpha: 0.75, Properties: []string{"name", "CapitalizedName"}},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination, HybridSearch: &searchparams.HybridSearch{Query: "query", FusionAlgorithm: common_filters.HybridRankedFusion, Alpha: 0.75, Properties: []string{"name", "capitalizedName"}},
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
},
error: false,
},
{
name: "hybrid relative",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true, Certainty: false},
HybridSearch: &pb.Hybrid{Query: "query", FusionType: pb.Hybrid_FUSION_TYPE_RELATIVE_SCORE},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination, HybridSearch: &searchparams.HybridSearch{Query: "query", FusionAlgorithm: common_filters.HybridRelativeScoreFusion},
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
},
error: false,
},
{
name: "hybrid default",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true, Certainty: false},
HybridSearch: &pb.Hybrid{Query: "query"},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination, HybridSearch: &searchparams.HybridSearch{Query: "query", FusionAlgorithm: common_filters.HybridRelativeScoreFusion},
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
},
error: false,
},
{
name: "bm25",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
Bm25Search: &pb.BM25{Query: "query", Properties: []string{"name", "CapitalizedName"}},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
KeywordRanking: &searchparams.KeywordRanking{Query: "query", Properties: []string{"name", "capitalizedName"}, Type: "bm25"},
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
},
error: false,
},
{
name: "filter simple",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
Filters: &pb.Filters{Operator: pb.Filters_OPERATOR_EQUAL, TestValue: &pb.Filters_ValueText{ValueText: "test"}, On: []string{"name"}},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
Filters: &filters.LocalFilter{
Root: &filters.Clause{
On: &filters.Path{Class: schema.ClassName(classname), Property: "name"},
Operator: filters.OperatorEqual,
Value: &filters.Value{Value: "test", Type: schema.DataTypeText},
},
},
},
error: false,
},
{
name: "filter simple (new type)",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
Filters: &pb.Filters{Operator: pb.Filters_OPERATOR_EQUAL, TestValue: &pb.Filters_ValueText{ValueText: "test"}, Target: &pb.FilterTarget{Target: &pb.FilterTarget_Property{Property: "name"}}},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
Filters: &filters.LocalFilter{
Root: &filters.Clause{
On: &filters.Path{Class: schema.ClassName(classname), Property: "name"},
Operator: filters.OperatorEqual,
Value: &filters.Value{Value: "test", Type: schema.DataTypeText},
},
},
},
error: false,
},
{
name: "filter uuid",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
Filters: &pb.Filters{Operator: pb.Filters_OPERATOR_EQUAL, TestValue: &pb.Filters_ValueText{ValueText: UUID3}, On: []string{"uuid"}},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
Filters: &filters.LocalFilter{
Root: &filters.Clause{
On: &filters.Path{Class: schema.ClassName(classname), Property: "uuid"},
Operator: filters.OperatorEqual,
Value: &filters.Value{Value: UUID3, Type: schema.DataTypeText},
},
},
},
error: false,
},
{
name: "filter or",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
Filters: &pb.Filters{Operator: pb.Filters_OPERATOR_OR, Filters: []*pb.Filters{
{Operator: pb.Filters_OPERATOR_EQUAL, TestValue: &pb.Filters_ValueText{ValueText: "test"}, On: []string{"name"}},
{Operator: pb.Filters_OPERATOR_NOT_EQUAL, TestValue: &pb.Filters_ValueText{ValueText: "other"}, On: []string{"name"}},
}},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
Filters: &filters.LocalFilter{
Root: &filters.Clause{
Operator: filters.OperatorOr,
Operands: []filters.Clause{
{
Value: &filters.Value{Value: "test", Type: schema.DataTypeText},
On: &filters.Path{Class: schema.ClassName(classname), Property: "name"},
Operator: filters.OperatorEqual,
},
{
Value: &filters.Value{Value: "other", Type: schema.DataTypeText},
On: &filters.Path{Class: schema.ClassName(classname), Property: "name"},
Operator: filters.OperatorNotEqual,
},
},
},
},
},
error: false,
},
{
name: "filter reference",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
Filters: &pb.Filters{Operator: pb.Filters_OPERATOR_LESS_THAN, TestValue: &pb.Filters_ValueText{ValueText: "test"}, On: []string{"ref", refClass1, "something"}},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
Filters: &filters.LocalFilter{
Root: &filters.Clause{
On: &filters.Path{
Class: schema.ClassName(classname),
Property: "ref",
Child: &filters.Path{Class: schema.ClassName(refClass1), Property: "something"},
},
Operator: filters.OperatorLessThan,
Value: &filters.Value{Value: "test", Type: schema.DataTypeText},
},
},
},
error: false,
},
{
name: "filter reference (new filters)",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
Filters: &pb.Filters{Operator: pb.Filters_OPERATOR_LESS_THAN, TestValue: &pb.Filters_ValueText{ValueText: "test"}, Target: &pb.FilterTarget{Target: &pb.FilterTarget_SingleTarget{SingleTarget: &pb.FilterReferenceSingleTarget{On: "ref", Target: &pb.FilterTarget{Target: &pb.FilterTarget_Property{Property: "something"}}}}}},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
Filters: &filters.LocalFilter{
Root: &filters.Clause{
On: &filters.Path{
Class: schema.ClassName(classname),
Property: "ref",
Child: &filters.Path{Class: schema.ClassName(refClass1), Property: "something"},
},
Operator: filters.OperatorLessThan,
Value: &filters.Value{Value: "test", Type: schema.DataTypeText},
},
},
},
error: false,
},
{
name: "nested ref",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
Filters: &pb.Filters{Operator: pb.Filters_OPERATOR_LESS_THAN, TestValue: &pb.Filters_ValueText{ValueText: "test"}, On: []string{"ref", refClass1, "ref2", refClass2, "ref3", refClass2, "else"}},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
Filters: &filters.LocalFilter{
Root: &filters.Clause{
On: &filters.Path{
Class: schema.ClassName(classname),
Property: "ref",
Child: &filters.Path{
Class: schema.ClassName(refClass1),
Property: "ref2",
Child: &filters.Path{
Class: schema.ClassName(refClass2),
Property: "ref3",
Child: &filters.Path{
Class: schema.ClassName(refClass2),
Property: "else",
},
},
},
},
Operator: filters.OperatorLessThan,
Value: &filters.Value{Value: "test", Type: schema.DataTypeText},
},
},
},
error: false,
},
{
name: "filter reference on array prop with contains",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
Filters: &pb.Filters{Operator: pb.Filters_OPERATOR_CONTAINS_ANY, TestValue: &pb.Filters_ValueTextArray{ValueTextArray: &pb.TextArray{Values: []string{"text"}}}, On: []string{"ref", refClass1, "somethings"}},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
Filters: &filters.LocalFilter{
Root: &filters.Clause{
On: &filters.Path{
Class: schema.ClassName(classname),
Property: "ref",
Child: &filters.Path{
Class: schema.ClassName(refClass1),
Property: "somethings",
},
},
Operator: filters.ContainsAny,
Value: &filters.Value{Value: []string{"text"}, Type: schema.DataTypeText},
},
},
},
error: false,
},
{
name: "filter reference",
req: &pb.SearchRequest{
Collection: classname,
Filters: &pb.Filters{
Operator: pb.Filters_OPERATOR_LESS_THAN,
TestValue: &pb.Filters_ValueText{ValueText: "test"},
On: []string{"ref", refClass1}, // two values do not work, property is missing
},
},
out: dto.GetParams{},
error: true,
},
{
name: "length filter ref",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
Filters: &pb.Filters{
Operator: pb.Filters_OPERATOR_LESS_THAN,
TestValue: &pb.Filters_ValueInt{ValueInt: 3},
On: []string{"ref", refClass1, "len(something)"},
},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
Filters: &filters.LocalFilter{
Root: &filters.Clause{
On: &filters.Path{
Class: schema.ClassName(classname),
Property: "ref",
Child: &filters.Path{
Class: schema.ClassName(refClass1),
Property: "len(something)",
},
},
Operator: filters.OperatorLessThan,
Value: &filters.Value{Value: 3, Type: schema.DataTypeInt},
},
},
},
error: false,
},
{
name: "length filter",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
Filters: &pb.Filters{
Operator: pb.Filters_OPERATOR_LESS_THAN,
TestValue: &pb.Filters_ValueInt{ValueInt: 3},
On: []string{"len(name)"},
},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
Filters: &filters.LocalFilter{
Root: &filters.Clause{
On: &filters.Path{
Class: schema.ClassName(classname),
Property: "len(name)",
},
Operator: filters.OperatorLessThan,
Value: &filters.Value{Value: 3, Type: schema.DataTypeInt},
},
},
},
error: false,
},
{
name: "contains filter with int value on float prop",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
Filters: &pb.Filters{
Operator: pb.Filters_OPERATOR_CONTAINS_ALL,
TestValue: &pb.Filters_ValueIntArray{ValueIntArray: &pb.IntArray{Values: []int64{3}}},
On: []string{"floats"},
},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
Filters: &filters.LocalFilter{
Root: &filters.Clause{
On: &filters.Path{
Class: schema.ClassName(classname),
Property: "floats",
},
Operator: filters.ContainsAll,
Value: &filters.Value{Value: []float64{3}, Type: schema.DataTypeNumber},
},
},
},
error: false,
},
{
name: "metadata filter id",
req: &pb.SearchRequest{
Collection: classname,
Filters: &pb.Filters{
Operator: pb.Filters_OPERATOR_EQUAL,
TestValue: &pb.Filters_ValueText{ValueText: UUID4},
On: []string{filters.InternalPropID},
},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{NoProps: false},
Filters: &filters.LocalFilter{
Root: &filters.Clause{
On: &filters.Path{
Class: schema.ClassName(classname),
Property: filters.InternalPropID,
},
Operator: filters.OperatorEqual,
Value: &filters.Value{Value: UUID4, Type: schema.DataTypeText},
},
},
},
error: false,
},
{
name: "metadata filter time",
req: &pb.SearchRequest{
Collection: classname,
Filters: &pb.Filters{
Operator: pb.Filters_OPERATOR_EQUAL,
TestValue: &pb.Filters_ValueText{ValueText: "2022-03-18T20:26:34.586-05:00"},
On: []string{filters.InternalPropCreationTimeUnix},
},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{NoProps: false},
Filters: &filters.LocalFilter{
Root: &filters.Clause{
On: &filters.Path{
Class: schema.ClassName(classname),
Property: filters.InternalPropCreationTimeUnix,
},
Operator: filters.OperatorEqual,
Value: &filters.Value{Value: "2022-03-18T20:26:34.586-05:00", Type: schema.DataTypeDate},
},
},
},
error: false,
},
{
name: "near text search",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
NearText: &pb.NearTextSearch{
Query: []string{"first and", "second", "query"},
MoveTo: &pb.NearTextSearch_Move{Force: 0.5, Concepts: []string{"first", "and second"}, Uuids: []string{UUID3, UUID4}},
MoveAway: &pb.NearTextSearch_Move{Force: 0.3, Concepts: []string{"second to last", "really last"}, Uuids: []string{UUID4}},
},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
ModuleParams: map[string]interface{}{
"nearText": &nearText2.NearTextParams{
Values: []string{"first and", "second", "query"},
MoveTo: nearText2.ExploreMove{
Force: 0.5,
Values: []string{"first", "and second"},
Objects: []nearText2.ObjectMove{
{ID: UUID3, Beacon: crossref.NewLocalhost(classname, UUID3).String()},
{ID: UUID4, Beacon: crossref.NewLocalhost(classname, UUID4).String()},
},
},
MoveAwayFrom: nearText2.ExploreMove{
Force: 0.3,
Values: []string{"second to last", "really last"},
Objects: []nearText2.ObjectMove{
{ID: UUID4, Beacon: crossref.NewLocalhost(classname, UUID4).String()},
},
},
Limit: 10, // default
},
},
},
error: false,
},
{
name: "near text wrong uuid format",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
NearText: &pb.NearTextSearch{
Query: []string{"first"},
MoveTo: &pb.NearTextSearch_Move{Force: 0.5, Uuids: []string{"not a uuid"}},
},
},
out: dto.GetParams{},
error: true,
},
{
name: "near audio search",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
NearAudio: &pb.NearAudioSearch{
Audio: "audio file",
},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
ModuleParams: map[string]interface{}{
"nearAudio": &nearAudio.NearAudioParams{
Audio: "audio file",
},
},
},
error: false,
},
{
name: "near video search",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
NearVideo: &pb.NearVideoSearch{
Video: "video file",
},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
ModuleParams: map[string]interface{}{
"nearVideo": &nearVideo.NearVideoParams{
Video: "video file",
},
},
},
error: false,
},
{
name: "near image search",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
NearImage: &pb.NearImageSearch{
Image: "image file",
},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
ModuleParams: map[string]interface{}{
"nearImage": &nearImage.NearImageParams{
Image: "image file",
},
},
},
error: false,
},
{
name: "Consistency",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
ConsistencyLevel: &quorum,
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
ReplicationProperties: &additional.ReplicationProperties{ConsistencyLevel: "QUORUM"},
},
error: false,
},
{
name: "Generative",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
Generative: &pb.GenerativeSearch{SingleResponsePrompt: someString1, GroupedResponseTask: someString2, GroupedProperties: []string{"one", "two"}},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{
Vector: true,
NoProps: false,
ModuleParams: map[string]interface{}{
"generate": &generate.Params{Prompt: &someString1, Task: &someString2, Properties: []string{"one", "two"}},
},
},
},
error: false,
},
{
name: "Sort",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
SortBy: []*pb.SortBy{{Ascending: false, Path: []string{"name"}}},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{
Vector: true,
NoProps: false,
},
Sort: []filters.Sort{{Order: "desc", Path: []string{"name"}}},
},
error: false,
},
{
name: "Sort and vector search",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
SortBy: []*pb.SortBy{{Ascending: false, Path: []string{"name"}}},
NearVector: &pb.NearVector{Vector: []float32{1, 2, 3}},
},
out: dto.GetParams{},
error: true,
},
{
name: "group by",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
GroupBy: &pb.GroupBy{Path: []string{"name"}, NumberOfGroups: 2, ObjectsPerGroup: 3},
NearVector: &pb.NearVector{Vector: []float32{1, 2, 3}},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{
Vector: true,
NoProps: false,
Group: true,
},
NearVector: &searchparams.NearVector{Vector: []float32{1, 2, 3}},
GroupBy: &searchparams.GroupBy{Groups: 2, ObjectsPerGroup: 3, Property: "name"},
},
error: false,
},
{
name: "group by with too long path",
req: &pb.SearchRequest{
Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
GroupBy: &pb.GroupBy{Path: []string{"ref", "Class"}, NumberOfGroups: 2, ObjectsPerGroup: 3},
NearVector: &pb.NearVector{Vector: []float32{1, 2, 3}},
},
out: dto.GetParams{},
error: true,
},
{
name: "Object properties return",
req: &pb.SearchRequest{
Collection: objClass,
Properties: &pb.PropertiesRequest{
ObjectProperties: []*pb.ObjectPropertiesRequest{
{
PropName: "something",
PrimitiveProperties: []string{"name"},
ObjectProperties: []*pb.ObjectPropertiesRequest{
{
PropName: "else",
PrimitiveProperties: []string{"name"},
},
{
PropName: "elses",
PrimitiveProperties: []string{"name"},
},
},
},
},
},
},
out: dto.GetParams{
ClassName: objClass, Pagination: defaultPagination,
Properties: search.SelectProperties{
{
Name: "something", IsPrimitive: false, IsObject: true,
Props: search.SelectProperties{
{Name: "name", IsPrimitive: true},
{
Name: "else", IsPrimitive: false, IsObject: true,
Props: search.SelectProperties{{
Name: "name", IsPrimitive: true,
}},
},
{
Name: "elses", IsPrimitive: false, IsObject: true,
Props: search.SelectProperties{{
Name: "name", IsPrimitive: true,
}},
},
},
},
},
},
},
{
name: "Empty return values given nested",
req: &pb.SearchRequest{Collection: objClass},
out: dto.GetParams{
ClassName: objClass, Pagination: defaultPagination,
Properties: search.SelectProperties{
{
Name: "something", IsPrimitive: false, IsObject: true,
Props: search.SelectProperties{
{Name: "name", IsPrimitive: true},
{
Name: "else", IsPrimitive: false, IsObject: true,
Props: search.SelectProperties{{
Name: "name", IsPrimitive: true,
}},
},
{
Name: "elses", IsPrimitive: false, IsObject: true,
Props: search.SelectProperties{{
Name: "name", IsPrimitive: true,
}},
},
},
},
},
},
error: false,
},
{
name: "No return values given nested with new default logic",
req: &pb.SearchRequest{Uses_123Api: true, Collection: objClass, Properties: &pb.PropertiesRequest{ReturnAllNonrefProperties: true}},
out: dto.GetParams{
ClassName: objClass, Pagination: defaultPagination,
Properties: search.SelectProperties{
{
Name: "something", IsPrimitive: false, IsObject: true,
Props: search.SelectProperties{
{Name: "name", IsPrimitive: true},
{
Name: "else", IsPrimitive: false, IsObject: true,
Props: search.SelectProperties{{
Name: "name", IsPrimitive: true,
}},
},
{
Name: "elses", IsPrimitive: false, IsObject: true,
Props: search.SelectProperties{{
Name: "name", IsPrimitive: true,
}},
},
},
},
},
},
error: false,
},
{
name: "Rerank without query",
req: &pb.SearchRequest{
Collection: classname,
Rerank: &pb.Rerank{Property: someString1},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{
NoProps: false,
ModuleParams: map[string]interface{}{"rerank": &rank.Params{Property: &someString1}},
},
},
error: false,
},
{
name: "Rerank with query",
req: &pb.SearchRequest{
Collection: classname,
Rerank: &pb.Rerank{Property: someString1, Query: &someString2},
},
out: dto.GetParams{
ClassName: classname, Pagination: defaultPagination,
Properties: defaultTestClassProps,
AdditionalProperties: additional.Properties{
NoProps: false,
ModuleParams: map[string]interface{}{"rerank": &rank.Params{Property: &someString1, Query: &someString2}},
},
},
error: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
out, err := searchParamsFromProto(tt.req, scheme)
if tt.error {
require.NotNil(t, err)
} else {
require.Nil(t, err)
require.Equal(t, tt.out, out)
}
})
}
}