github.com/weaviate/weaviate@v1.24.6/adapters/handlers/grpc/v1/parse_search_request_test.go (about)

     1  //                           _       _
     2  // __      _____  __ ___   ___  __ _| |_ ___
     3  // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
     4  //  \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
     5  //   \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
     6  //
     7  //  Copyright © 2016 - 2024 Weaviate B.V. All rights reserved.
     8  //
     9  //  CONTACT: hello@weaviate.io
    10  //
    11  
    12  package v1
    13  
    14  import (
    15  	"sort"
    16  	"testing"
    17  
    18  	"github.com/weaviate/weaviate/usecases/config"
    19  
    20  	"github.com/stretchr/testify/require"
    21  	"github.com/weaviate/weaviate/adapters/handlers/graphql/local/common_filters"
    22  	"github.com/weaviate/weaviate/entities/additional"
    23  	"github.com/weaviate/weaviate/entities/dto"
    24  	"github.com/weaviate/weaviate/entities/filters"
    25  	"github.com/weaviate/weaviate/entities/models"
    26  	"github.com/weaviate/weaviate/entities/schema"
    27  	"github.com/weaviate/weaviate/entities/schema/crossref"
    28  	"github.com/weaviate/weaviate/entities/search"
    29  	"github.com/weaviate/weaviate/entities/searchparams"
    30  	vectorIndex "github.com/weaviate/weaviate/entities/vectorindex/common"
    31  	"github.com/weaviate/weaviate/entities/vectorindex/flat"
    32  	"github.com/weaviate/weaviate/entities/vectorindex/hnsw"
    33  	pb "github.com/weaviate/weaviate/grpc/generated/protocol/v1"
    34  	"github.com/weaviate/weaviate/usecases/modulecomponents/additional/generate"
    35  	"github.com/weaviate/weaviate/usecases/modulecomponents/additional/rank"
    36  	"github.com/weaviate/weaviate/usecases/modulecomponents/arguments/nearAudio"
    37  	"github.com/weaviate/weaviate/usecases/modulecomponents/arguments/nearDepth"
    38  	"github.com/weaviate/weaviate/usecases/modulecomponents/arguments/nearImage"
    39  	"github.com/weaviate/weaviate/usecases/modulecomponents/arguments/nearImu"
    40  	nearText2 "github.com/weaviate/weaviate/usecases/modulecomponents/arguments/nearText"
    41  	"github.com/weaviate/weaviate/usecases/modulecomponents/arguments/nearThermal"
    42  	"github.com/weaviate/weaviate/usecases/modulecomponents/arguments/nearVideo"
    43  )
    44  
    45  func TestGRPCRequest(t *testing.T) {
    46  	classname := "TestClass"
    47  	refClass1 := "OtherClass"
    48  	refClass2 := "AnotherClass"
    49  	dotClass := "DotClass"
    50  	objClass := "ObjClass"
    51  	multiVecClass := "MultiVecClass"
    52  
    53  	defaultTestClassProps := search.SelectProperties{{Name: "name", IsPrimitive: true}, {Name: "number", IsPrimitive: true}, {Name: "floats", IsPrimitive: true}, {Name: "uuid", IsPrimitive: true}}
    54  
    55  	scheme := schema.Schema{
    56  		Objects: &models.Schema{
    57  			Classes: []*models.Class{
    58  				{
    59  					Class: classname,
    60  					Properties: []*models.Property{
    61  						{Name: "name", DataType: schema.DataTypeText.PropString()},
    62  						{Name: "number", DataType: schema.DataTypeInt.PropString()},
    63  						{Name: "floats", DataType: schema.DataTypeNumberArray.PropString()},
    64  						{Name: "uuid", DataType: schema.DataTypeUUID.PropString()},
    65  						{Name: "ref", DataType: []string{refClass1}},
    66  						{Name: "multiRef", DataType: []string{refClass1, refClass2}},
    67  					},
    68  					VectorIndexConfig: hnsw.UserConfig{Distance: vectorIndex.DefaultDistanceMetric},
    69  				},
    70  				{
    71  					Class: refClass1,
    72  					Properties: []*models.Property{
    73  						{Name: "something", DataType: schema.DataTypeText.PropString()},
    74  						{Name: "somethings", DataType: schema.DataTypeTextArray.PropString()},
    75  						{Name: "ref2", DataType: []string{refClass2}},
    76  					},
    77  					VectorIndexConfig: hnsw.UserConfig{Distance: vectorIndex.DefaultDistanceMetric},
    78  				},
    79  				{
    80  					Class: refClass2,
    81  					Properties: []*models.Property{
    82  						{Name: "else", DataType: schema.DataTypeText.PropString()},
    83  						{Name: "ref3", DataType: []string{refClass2}},
    84  					},
    85  				},
    86  				{
    87  					Class: dotClass,
    88  					Properties: []*models.Property{
    89  						{Name: "something", DataType: schema.DataTypeText.PropString()},
    90  					},
    91  					VectorIndexConfig: hnsw.UserConfig{Distance: vectorIndex.DistanceDot},
    92  				},
    93  				{
    94  					Class: objClass,
    95  					Properties: []*models.Property{
    96  						{
    97  							Name:     "something",
    98  							DataType: schema.DataTypeObject.PropString(),
    99  							NestedProperties: []*models.NestedProperty{
   100  								{
   101  									Name:     "name",
   102  									DataType: schema.DataTypeText.PropString(),
   103  								},
   104  								{
   105  									Name:     "else",
   106  									DataType: schema.DataTypeObject.PropString(),
   107  									NestedProperties: []*models.NestedProperty{
   108  										{
   109  											Name:     "name",
   110  											DataType: schema.DataTypeText.PropString(),
   111  										},
   112  									},
   113  								},
   114  								{
   115  									Name:     "elses",
   116  									DataType: schema.DataTypeObjectArray.PropString(),
   117  									NestedProperties: []*models.NestedProperty{
   118  										{
   119  											Name:     "name",
   120  											DataType: schema.DataTypeText.PropString(),
   121  										},
   122  									},
   123  								},
   124  							},
   125  						},
   126  					},
   127  					VectorIndexConfig: hnsw.UserConfig{Distance: vectorIndex.DefaultDistanceMetric},
   128  				},
   129  				{
   130  					Class: multiVecClass,
   131  					Properties: []*models.Property{
   132  						{Name: "first", DataType: schema.DataTypeText.PropString()},
   133  					},
   134  					VectorConfig: map[string]models.VectorConfig{
   135  						"custom": {
   136  							VectorIndexType:   "hnsw",
   137  							VectorIndexConfig: hnsw.UserConfig{},
   138  							Vectorizer:        map[string]interface{}{"none": map[string]interface{}{}},
   139  						},
   140  						"first": {
   141  							VectorIndexType:   "flat",
   142  							VectorIndexConfig: flat.UserConfig{},
   143  							Vectorizer:        map[string]interface{}{"text2vec-contextionary": map[string]interface{}{}},
   144  						},
   145  					},
   146  				},
   147  			},
   148  		},
   149  	}
   150  	defaultPagination := &filters.Pagination{Limit: 10}
   151  	quorum := pb.ConsistencyLevel_CONSISTENCY_LEVEL_QUORUM
   152  	someString1 := "a word"
   153  	someString2 := "other"
   154  
   155  	tests := []struct {
   156  		name  string
   157  		req   *pb.SearchRequest
   158  		out   dto.GetParams
   159  		error bool
   160  	}{
   161  		{
   162  			name:  "No classname",
   163  			req:   &pb.SearchRequest{},
   164  			out:   dto.GetParams{},
   165  			error: true,
   166  		},
   167  		{
   168  			name: "No return values given",
   169  			req:  &pb.SearchRequest{Collection: classname},
   170  			out: dto.GetParams{
   171  				ClassName: classname, Pagination: defaultPagination, Properties: defaultTestClassProps,
   172  			},
   173  			error: false,
   174  		},
   175  		{
   176  			name: "Empty return properties given",
   177  			req:  &pb.SearchRequest{Collection: classname, Properties: &pb.PropertiesRequest{}},
   178  			out: dto.GetParams{
   179  				ClassName: classname, Pagination: defaultPagination, Properties: search.SelectProperties{}, AdditionalProperties: additional.Properties{
   180  					NoProps: true,
   181  				},
   182  			},
   183  			error: false,
   184  		},
   185  		{
   186  			name: "Empty return properties given with new default logic",
   187  			req:  &pb.SearchRequest{Uses_123Api: true, Collection: classname, Properties: &pb.PropertiesRequest{}},
   188  			out: dto.GetParams{
   189  				ClassName: classname, Pagination: defaultPagination, Properties: search.SelectProperties{}, AdditionalProperties: additional.Properties{
   190  					NoProps: true,
   191  				},
   192  			},
   193  			error: false,
   194  		},
   195  		{
   196  			name: "No return values given for dot distance",
   197  			req:  &pb.SearchRequest{Collection: dotClass},
   198  			out: dto.GetParams{
   199  				ClassName: dotClass, Pagination: defaultPagination, Properties: search.SelectProperties{{Name: "something", IsPrimitive: true}},
   200  			},
   201  			error: false,
   202  		},
   203  		{
   204  			name: "Metadata return values",
   205  			req:  &pb.SearchRequest{Collection: classname, Metadata: &pb.MetadataRequest{Vector: true, Certainty: false, IsConsistent: true}},
   206  			out: dto.GetParams{
   207  				ClassName: classname, Pagination: defaultPagination,
   208  				Properties: defaultTestClassProps,
   209  				AdditionalProperties: additional.Properties{
   210  					Vector:       true,
   211  					NoProps:      false,
   212  					IsConsistent: true,
   213  				},
   214  			},
   215  			error: false,
   216  		},
   217  		{
   218  			name: "Metadata ID only query",
   219  			req:  &pb.SearchRequest{Collection: classname, Properties: &pb.PropertiesRequest{}, Metadata: &pb.MetadataRequest{Uuid: true}},
   220  			out: dto.GetParams{
   221  				ClassName: classname, Pagination: defaultPagination,
   222  				Properties: search.SelectProperties{},
   223  				AdditionalProperties: additional.Properties{
   224  					ID:      true,
   225  					NoProps: true,
   226  				},
   227  			},
   228  			error: false,
   229  		},
   230  		{
   231  			name: "Metadata ID only query using new default logic",
   232  			req:  &pb.SearchRequest{Uses_123Api: true, Collection: classname, Properties: &pb.PropertiesRequest{}, Metadata: &pb.MetadataRequest{Uuid: true}},
   233  			out: dto.GetParams{
   234  				ClassName: classname, Pagination: defaultPagination,
   235  				Properties: search.SelectProperties{},
   236  				AdditionalProperties: additional.Properties{
   237  					ID:      true,
   238  					NoProps: true,
   239  				},
   240  			},
   241  			error: false,
   242  		},
   243  		{
   244  			name: "Properties return all nonref values",
   245  			req:  &pb.SearchRequest{Collection: classname},
   246  			out: dto.GetParams{
   247  				ClassName: classname, Pagination: defaultPagination, Properties: defaultTestClassProps,
   248  			},
   249  			error: false,
   250  		},
   251  		{
   252  			name: "Vectors returns all named vectors",
   253  			req: &pb.SearchRequest{
   254  				Collection: multiVecClass,
   255  				Metadata:   &pb.MetadataRequest{Vector: true},
   256  				Properties: &pb.PropertiesRequest{},
   257  				NearVector: &pb.NearVector{
   258  					Vector:        []float32{1, 2, 3},
   259  					TargetVectors: []string{"custom"},
   260  				},
   261  			},
   262  			out: dto.GetParams{
   263  				ClassName:            multiVecClass,
   264  				Pagination:           defaultPagination,
   265  				Properties:           search.SelectProperties{},
   266  				AdditionalProperties: additional.Properties{Vectors: []string{"custom", "first"}, Vector: true, NoProps: true},
   267  				NearVector: &searchparams.NearVector{
   268  					Vector:        []float32{1, 2, 3},
   269  					TargetVectors: []string{"custom"},
   270  				},
   271  			},
   272  			error: false,
   273  		},
   274  		{
   275  			name: "Vectors throws error if no target vectors are given",
   276  			req: &pb.SearchRequest{
   277  				Collection: multiVecClass,
   278  				Metadata:   &pb.MetadataRequest{Vector: true},
   279  				Properties: &pb.PropertiesRequest{},
   280  				NearVector: &pb.NearVector{
   281  					Vector: []float32{1, 2, 3},
   282  				},
   283  			},
   284  			out:   dto.GetParams{},
   285  			error: true,
   286  		},
   287  		{
   288  			name: "Vectors throws error if more than one target vectors are given",
   289  			req: &pb.SearchRequest{
   290  				Collection: multiVecClass,
   291  				Metadata:   &pb.MetadataRequest{Vector: true},
   292  				Properties: &pb.PropertiesRequest{},
   293  				NearVector: &pb.NearVector{
   294  					Vector:        []float32{1, 2, 3},
   295  					TargetVectors: []string{"custom", "first"},
   296  				},
   297  			},
   298  			out:   dto.GetParams{},
   299  			error: true,
   300  		},
   301  		{
   302  			name: "Properties return all nonref values with new default logic",
   303  			req:  &pb.SearchRequest{Uses_123Api: true, Collection: classname, Properties: &pb.PropertiesRequest{ReturnAllNonrefProperties: true}},
   304  			out: dto.GetParams{
   305  				ClassName: classname, Pagination: defaultPagination, Properties: defaultTestClassProps,
   306  			},
   307  			error: false,
   308  		},
   309  		{
   310  			name: "Properties return all nonref values with ref and specific props using new default logic",
   311  			req: &pb.SearchRequest{Uses_123Api: true, Collection: classname, Properties: &pb.PropertiesRequest{
   312  				ReturnAllNonrefProperties: true,
   313  				RefProperties: []*pb.RefPropertiesRequest{{
   314  					ReferenceProperty: "ref",
   315  					TargetCollection:  refClass1,
   316  					Metadata:          &pb.MetadataRequest{Vector: true, Certainty: false},
   317  					Properties:        &pb.PropertiesRequest{NonRefProperties: []string{"something"}},
   318  				}},
   319  			}},
   320  			out: dto.GetParams{
   321  				ClassName: classname, Pagination: defaultPagination, Properties: search.SelectProperties{
   322  					{Name: "name", IsPrimitive: true},
   323  					{Name: "number", IsPrimitive: true},
   324  					{Name: "floats", IsPrimitive: true},
   325  					{Name: "uuid", IsPrimitive: true},
   326  					{Name: "ref", IsPrimitive: false, Refs: []search.SelectClass{
   327  						{
   328  							ClassName:            refClass1,
   329  							RefProperties:        search.SelectProperties{{Name: "something", IsPrimitive: true}},
   330  							AdditionalProperties: additional.Properties{Vector: true},
   331  						},
   332  					}},
   333  				},
   334  			},
   335  			error: false,
   336  		},
   337  		{
   338  			name: "Properties return all nonref values with ref and all nonref props using new default logic",
   339  			req: &pb.SearchRequest{Uses_123Api: true, Collection: classname, Properties: &pb.PropertiesRequest{
   340  				ReturnAllNonrefProperties: true,
   341  				RefProperties: []*pb.RefPropertiesRequest{{
   342  					ReferenceProperty: "ref",
   343  					TargetCollection:  refClass1,
   344  					Metadata:          &pb.MetadataRequest{Vector: true, Certainty: false},
   345  					Properties:        &pb.PropertiesRequest{ReturnAllNonrefProperties: true},
   346  				}},
   347  			}},
   348  			out: dto.GetParams{
   349  				ClassName: classname, Pagination: defaultPagination, Properties: search.SelectProperties{
   350  					{Name: "name", IsPrimitive: true},
   351  					{Name: "number", IsPrimitive: true},
   352  					{Name: "floats", IsPrimitive: true},
   353  					{Name: "uuid", IsPrimitive: true},
   354  					{Name: "ref", IsPrimitive: false, Refs: []search.SelectClass{
   355  						{
   356  							ClassName: refClass1,
   357  							RefProperties: search.SelectProperties{
   358  								{Name: "something", IsPrimitive: true},
   359  								{Name: "somethings", IsPrimitive: true},
   360  							},
   361  							AdditionalProperties: additional.Properties{Vector: true},
   362  						},
   363  					}},
   364  				},
   365  			},
   366  			error: false,
   367  		},
   368  		{
   369  			name: "Properties return values only ref",
   370  			req: &pb.SearchRequest{Collection: classname, Properties: &pb.PropertiesRequest{
   371  				RefProperties: []*pb.RefPropertiesRequest{
   372  					{
   373  						ReferenceProperty: "ref",
   374  						TargetCollection:  refClass1,
   375  						Metadata:          &pb.MetadataRequest{Vector: true, Certainty: false},
   376  						Properties:        &pb.PropertiesRequest{NonRefProperties: []string{"something"}},
   377  					},
   378  				},
   379  			}},
   380  			out: dto.GetParams{
   381  				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{
   382  					Vector: true,
   383  				}}}}},
   384  			},
   385  			error: false,
   386  		},
   387  		{
   388  			name: "Properties return values only ref using new default logic",
   389  			req: &pb.SearchRequest{Uses_123Api: true, Collection: classname, Properties: &pb.PropertiesRequest{
   390  				RefProperties: []*pb.RefPropertiesRequest{
   391  					{
   392  						ReferenceProperty: "ref",
   393  						TargetCollection:  refClass1,
   394  						Metadata:          &pb.MetadataRequest{Vector: true, Certainty: false},
   395  						Properties:        &pb.PropertiesRequest{NonRefProperties: []string{"something"}},
   396  					},
   397  				},
   398  			}},
   399  			out: dto.GetParams{
   400  				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{
   401  					Vector: true,
   402  				}}}}},
   403  			},
   404  			error: false,
   405  		},
   406  		{
   407  			name: "Properties return values non-ref",
   408  			req:  &pb.SearchRequest{Collection: classname, Properties: &pb.PropertiesRequest{NonRefProperties: []string{"name", "CapitalizedName"}}},
   409  			out: dto.GetParams{
   410  				ClassName: classname, Pagination: defaultPagination, Properties: search.SelectProperties{{Name: "name", IsPrimitive: true}, {Name: "capitalizedName", IsPrimitive: true}},
   411  			},
   412  			error: false,
   413  		},
   414  		{
   415  			name: "Properties return values non-ref with new default logic",
   416  			req:  &pb.SearchRequest{Uses_123Api: true, Collection: classname, Properties: &pb.PropertiesRequest{NonRefProperties: []string{"name", "CapitalizedName"}}},
   417  			out: dto.GetParams{
   418  				ClassName: classname, Pagination: defaultPagination, Properties: search.SelectProperties{{Name: "name", IsPrimitive: true}, {Name: "capitalizedName", IsPrimitive: true}},
   419  			},
   420  			error: false,
   421  		},
   422  		{
   423  			name: "ref returns no values given",
   424  			req:  &pb.SearchRequest{Collection: classname, Properties: &pb.PropertiesRequest{RefProperties: []*pb.RefPropertiesRequest{{ReferenceProperty: "ref", TargetCollection: refClass1}}}},
   425  			out: dto.GetParams{
   426  				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}}}}}},
   427  			},
   428  			error: false,
   429  		},
   430  		{
   431  			name:  "Properties return values multi-ref (no linked class with error)",
   432  			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"}}}}}},
   433  			out:   dto.GetParams{},
   434  			error: true,
   435  		},
   436  		{
   437  			name: "Properties return values multi-ref",
   438  			req: &pb.SearchRequest{Collection: classname, Properties: &pb.PropertiesRequest{RefProperties: []*pb.RefPropertiesRequest{
   439  				{ReferenceProperty: "multiRef", TargetCollection: refClass1, Metadata: &pb.MetadataRequest{Vector: true, Certainty: false}, Properties: &pb.PropertiesRequest{NonRefProperties: []string{"something"}}},
   440  				{ReferenceProperty: "MultiRef", TargetCollection: refClass2, Metadata: &pb.MetadataRequest{Uuid: true}, Properties: &pb.PropertiesRequest{NonRefProperties: []string{"Else"}}},
   441  			}}},
   442  			out: dto.GetParams{
   443  				ClassName: classname, Pagination: defaultPagination, Properties: search.SelectProperties{
   444  					{Name: "multiRef", IsPrimitive: false, Refs: []search.SelectClass{{ClassName: refClass1, RefProperties: search.SelectProperties{{Name: "something", IsPrimitive: true}}, AdditionalProperties: additional.Properties{Vector: true}}}},
   445  					{Name: "multiRef", IsPrimitive: false, Refs: []search.SelectClass{{ClassName: refClass2, RefProperties: search.SelectProperties{{Name: "else", IsPrimitive: true}}, AdditionalProperties: additional.Properties{ID: true}}}},
   446  				},
   447  			},
   448  			error: false,
   449  		},
   450  		{
   451  			name: "hybrid ranked",
   452  			req: &pb.SearchRequest{
   453  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true, Certainty: false},
   454  				HybridSearch: &pb.Hybrid{Query: "query", FusionType: pb.Hybrid_FUSION_TYPE_RANKED, Alpha: 0.75, Properties: []string{"name", "CapitalizedName"}},
   455  			},
   456  			out: dto.GetParams{
   457  				ClassName: classname, Pagination: defaultPagination, HybridSearch: &searchparams.HybridSearch{Query: "query", FusionAlgorithm: common_filters.HybridRankedFusion, Alpha: 0.75, Properties: []string{"name", "capitalizedName"}},
   458  				Properties:           defaultTestClassProps,
   459  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   460  			},
   461  			error: false,
   462  		},
   463  		{
   464  			name: "hybrid targetvectors",
   465  			req: &pb.SearchRequest{
   466  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true, Certainty: false},
   467  				HybridSearch: &pb.Hybrid{TargetVectors: []string{"testname"}, Query: "query", FusionType: pb.Hybrid_FUSION_TYPE_RANKED, Alpha: 0.75, Properties: []string{"name", "CapitalizedName"}},
   468  			},
   469  			out: dto.GetParams{
   470  				ClassName: classname, Pagination: defaultPagination, HybridSearch: &searchparams.HybridSearch{TargetVectors: []string{"testname"}, Query: "query", FusionAlgorithm: common_filters.HybridRankedFusion, Alpha: 0.75, Properties: []string{"name", "capitalizedName"}},
   471  				Properties:           defaultTestClassProps,
   472  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   473  			},
   474  			error: false,
   475  		},
   476  		{
   477  			name: "hybrid relative",
   478  			req: &pb.SearchRequest{
   479  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true, Certainty: false},
   480  				HybridSearch: &pb.Hybrid{Query: "query", FusionType: pb.Hybrid_FUSION_TYPE_RELATIVE_SCORE},
   481  			},
   482  			out: dto.GetParams{
   483  				ClassName: classname, Pagination: defaultPagination, HybridSearch: &searchparams.HybridSearch{Query: "query", FusionAlgorithm: common_filters.HybridRelativeScoreFusion},
   484  				Properties:           defaultTestClassProps,
   485  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   486  			},
   487  			error: false,
   488  		},
   489  		{
   490  			name: "hybrid default",
   491  			req: &pb.SearchRequest{
   492  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true, Certainty: false},
   493  				HybridSearch: &pb.Hybrid{Query: "query"},
   494  			},
   495  			out: dto.GetParams{
   496  				ClassName: classname, Pagination: defaultPagination, HybridSearch: &searchparams.HybridSearch{Query: "query", FusionAlgorithm: common_filters.HybridRelativeScoreFusion},
   497  				Properties:           defaultTestClassProps,
   498  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   499  			},
   500  			error: false,
   501  		},
   502  		{
   503  			name: "bm25",
   504  			req: &pb.SearchRequest{
   505  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
   506  				Bm25Search: &pb.BM25{Query: "query", Properties: []string{"name", "CapitalizedName"}},
   507  			},
   508  			out: dto.GetParams{
   509  				ClassName: classname, Pagination: defaultPagination,
   510  				KeywordRanking:       &searchparams.KeywordRanking{Query: "query", Properties: []string{"name", "capitalizedName"}, Type: "bm25"},
   511  				Properties:           defaultTestClassProps,
   512  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   513  			},
   514  			error: false,
   515  		},
   516  		{
   517  			name: "filter simple",
   518  			req: &pb.SearchRequest{
   519  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
   520  				Filters: &pb.Filters{Operator: pb.Filters_OPERATOR_EQUAL, TestValue: &pb.Filters_ValueText{ValueText: "test"}, On: []string{"name"}},
   521  			},
   522  			out: dto.GetParams{
   523  				ClassName: classname, Pagination: defaultPagination,
   524  				Properties:           defaultTestClassProps,
   525  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   526  				Filters: &filters.LocalFilter{
   527  					Root: &filters.Clause{
   528  						On:       &filters.Path{Class: schema.ClassName(classname), Property: "name"},
   529  						Operator: filters.OperatorEqual,
   530  						Value:    &filters.Value{Value: "test", Type: schema.DataTypeText},
   531  					},
   532  				},
   533  			},
   534  			error: false,
   535  		},
   536  		{
   537  			name: "filter simple (new type)",
   538  			req: &pb.SearchRequest{
   539  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
   540  				Filters: &pb.Filters{Operator: pb.Filters_OPERATOR_EQUAL, TestValue: &pb.Filters_ValueText{ValueText: "test"}, Target: &pb.FilterTarget{Target: &pb.FilterTarget_Property{Property: "name"}}},
   541  			},
   542  			out: dto.GetParams{
   543  				ClassName: classname, Pagination: defaultPagination,
   544  				Properties:           defaultTestClassProps,
   545  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   546  				Filters: &filters.LocalFilter{
   547  					Root: &filters.Clause{
   548  						On:       &filters.Path{Class: schema.ClassName(classname), Property: "name"},
   549  						Operator: filters.OperatorEqual,
   550  						Value:    &filters.Value{Value: "test", Type: schema.DataTypeText},
   551  					},
   552  				},
   553  			},
   554  			error: false,
   555  		},
   556  		{
   557  			name: "filter uuid",
   558  			req: &pb.SearchRequest{
   559  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
   560  				Filters: &pb.Filters{Operator: pb.Filters_OPERATOR_EQUAL, TestValue: &pb.Filters_ValueText{ValueText: UUID3}, On: []string{"uuid"}},
   561  			},
   562  			out: dto.GetParams{
   563  				ClassName: classname, Pagination: defaultPagination,
   564  				Properties:           defaultTestClassProps,
   565  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   566  				Filters: &filters.LocalFilter{
   567  					Root: &filters.Clause{
   568  						On:       &filters.Path{Class: schema.ClassName(classname), Property: "uuid"},
   569  						Operator: filters.OperatorEqual,
   570  						Value:    &filters.Value{Value: UUID3, Type: schema.DataTypeText},
   571  					},
   572  				},
   573  			},
   574  			error: false,
   575  		},
   576  		{
   577  			name: "filter or",
   578  			req: &pb.SearchRequest{
   579  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
   580  				Filters: &pb.Filters{Operator: pb.Filters_OPERATOR_OR, Filters: []*pb.Filters{
   581  					{Operator: pb.Filters_OPERATOR_EQUAL, TestValue: &pb.Filters_ValueText{ValueText: "test"}, On: []string{"name"}},
   582  					{Operator: pb.Filters_OPERATOR_NOT_EQUAL, TestValue: &pb.Filters_ValueText{ValueText: "other"}, On: []string{"name"}},
   583  				}},
   584  			},
   585  			out: dto.GetParams{
   586  				ClassName: classname, Pagination: defaultPagination,
   587  				Properties:           defaultTestClassProps,
   588  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   589  				Filters: &filters.LocalFilter{
   590  					Root: &filters.Clause{
   591  						Operator: filters.OperatorOr,
   592  						Operands: []filters.Clause{
   593  							{
   594  								Value:    &filters.Value{Value: "test", Type: schema.DataTypeText},
   595  								On:       &filters.Path{Class: schema.ClassName(classname), Property: "name"},
   596  								Operator: filters.OperatorEqual,
   597  							},
   598  							{
   599  								Value:    &filters.Value{Value: "other", Type: schema.DataTypeText},
   600  								On:       &filters.Path{Class: schema.ClassName(classname), Property: "name"},
   601  								Operator: filters.OperatorNotEqual,
   602  							},
   603  						},
   604  					},
   605  				},
   606  			},
   607  			error: false,
   608  		},
   609  		{
   610  			name: "filter reference",
   611  			req: &pb.SearchRequest{
   612  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
   613  				Filters: &pb.Filters{Operator: pb.Filters_OPERATOR_LESS_THAN, TestValue: &pb.Filters_ValueText{ValueText: "test"}, On: []string{"ref", refClass1, "something"}},
   614  			},
   615  			out: dto.GetParams{
   616  				ClassName: classname, Pagination: defaultPagination,
   617  				Properties:           defaultTestClassProps,
   618  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   619  				Filters: &filters.LocalFilter{
   620  					Root: &filters.Clause{
   621  						On: &filters.Path{
   622  							Class:    schema.ClassName(classname),
   623  							Property: "ref",
   624  							Child:    &filters.Path{Class: schema.ClassName(refClass1), Property: "something"},
   625  						},
   626  						Operator: filters.OperatorLessThan,
   627  						Value:    &filters.Value{Value: "test", Type: schema.DataTypeText},
   628  					},
   629  				},
   630  			},
   631  			error: false,
   632  		},
   633  		{
   634  			name: "filter reference (new filters)",
   635  			req: &pb.SearchRequest{
   636  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
   637  				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"}}}}}},
   638  			},
   639  			out: dto.GetParams{
   640  				ClassName: classname, Pagination: defaultPagination,
   641  				Properties:           defaultTestClassProps,
   642  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   643  				Filters: &filters.LocalFilter{
   644  					Root: &filters.Clause{
   645  						On: &filters.Path{
   646  							Class:    schema.ClassName(classname),
   647  							Property: "ref",
   648  							Child:    &filters.Path{Class: schema.ClassName(refClass1), Property: "something"},
   649  						},
   650  						Operator: filters.OperatorLessThan,
   651  						Value:    &filters.Value{Value: "test", Type: schema.DataTypeText},
   652  					},
   653  				},
   654  			},
   655  			error: false,
   656  		},
   657  		{
   658  			name: "nested ref",
   659  			req: &pb.SearchRequest{
   660  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
   661  				Filters: &pb.Filters{Operator: pb.Filters_OPERATOR_LESS_THAN, TestValue: &pb.Filters_ValueText{ValueText: "test"}, On: []string{"ref", refClass1, "ref2", refClass2, "ref3", refClass2, "else"}},
   662  			},
   663  			out: dto.GetParams{
   664  				ClassName: classname, Pagination: defaultPagination,
   665  				Properties:           defaultTestClassProps,
   666  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   667  				Filters: &filters.LocalFilter{
   668  					Root: &filters.Clause{
   669  						On: &filters.Path{
   670  							Class:    schema.ClassName(classname),
   671  							Property: "ref",
   672  							Child: &filters.Path{
   673  								Class:    schema.ClassName(refClass1),
   674  								Property: "ref2",
   675  								Child: &filters.Path{
   676  									Class:    schema.ClassName(refClass2),
   677  									Property: "ref3",
   678  									Child: &filters.Path{
   679  										Class:    schema.ClassName(refClass2),
   680  										Property: "else",
   681  									},
   682  								},
   683  							},
   684  						},
   685  						Operator: filters.OperatorLessThan,
   686  						Value:    &filters.Value{Value: "test", Type: schema.DataTypeText},
   687  					},
   688  				},
   689  			},
   690  			error: false,
   691  		},
   692  		{
   693  			name: "filter reference on array prop with contains",
   694  			req: &pb.SearchRequest{
   695  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
   696  				Filters: &pb.Filters{Operator: pb.Filters_OPERATOR_CONTAINS_ANY, TestValue: &pb.Filters_ValueTextArray{ValueTextArray: &pb.TextArray{Values: []string{"text"}}}, On: []string{"ref", refClass1, "somethings"}},
   697  			},
   698  			out: dto.GetParams{
   699  				ClassName: classname, Pagination: defaultPagination,
   700  				Properties:           defaultTestClassProps,
   701  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   702  				Filters: &filters.LocalFilter{
   703  					Root: &filters.Clause{
   704  						On: &filters.Path{
   705  							Class:    schema.ClassName(classname),
   706  							Property: "ref",
   707  							Child: &filters.Path{
   708  								Class:    schema.ClassName(refClass1),
   709  								Property: "somethings",
   710  							},
   711  						},
   712  						Operator: filters.ContainsAny,
   713  						Value:    &filters.Value{Value: []string{"text"}, Type: schema.DataTypeText},
   714  					},
   715  				},
   716  			},
   717  			error: false,
   718  		},
   719  		{
   720  			name: "filter reference",
   721  			req: &pb.SearchRequest{
   722  				Collection: classname,
   723  				Filters: &pb.Filters{
   724  					Operator:  pb.Filters_OPERATOR_LESS_THAN,
   725  					TestValue: &pb.Filters_ValueText{ValueText: "test"},
   726  					On:        []string{"ref", refClass1}, // two values do not work, property is missing
   727  				},
   728  			},
   729  			out:   dto.GetParams{},
   730  			error: true,
   731  		},
   732  		{
   733  			name: "length filter ref",
   734  			req: &pb.SearchRequest{
   735  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
   736  				Filters: &pb.Filters{
   737  					Operator:  pb.Filters_OPERATOR_LESS_THAN,
   738  					TestValue: &pb.Filters_ValueInt{ValueInt: 3},
   739  					On:        []string{"ref", refClass1, "len(something)"},
   740  				},
   741  			},
   742  			out: dto.GetParams{
   743  				ClassName: classname, Pagination: defaultPagination,
   744  				Properties:           defaultTestClassProps,
   745  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   746  				Filters: &filters.LocalFilter{
   747  					Root: &filters.Clause{
   748  						On: &filters.Path{
   749  							Class:    schema.ClassName(classname),
   750  							Property: "ref",
   751  							Child: &filters.Path{
   752  								Class:    schema.ClassName(refClass1),
   753  								Property: "len(something)",
   754  							},
   755  						},
   756  						Operator: filters.OperatorLessThan,
   757  						Value:    &filters.Value{Value: 3, Type: schema.DataTypeInt},
   758  					},
   759  				},
   760  			},
   761  			error: false,
   762  		},
   763  		{
   764  			name: "count filter single target ref old",
   765  			req: &pb.SearchRequest{
   766  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
   767  				Filters: &pb.Filters{
   768  					Operator:  pb.Filters_OPERATOR_LESS_THAN,
   769  					TestValue: &pb.Filters_ValueInt{ValueInt: 3},
   770  					On:        []string{"ref"},
   771  				},
   772  			},
   773  			out: dto.GetParams{
   774  				ClassName: classname, Pagination: defaultPagination,
   775  				Properties:           defaultTestClassProps,
   776  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   777  				Filters: &filters.LocalFilter{
   778  					Root: &filters.Clause{
   779  						On: &filters.Path{
   780  							Class:    schema.ClassName(classname),
   781  							Property: "ref",
   782  						},
   783  						Operator: filters.OperatorLessThan,
   784  						Value:    &filters.Value{Value: 3, Type: schema.DataTypeInt},
   785  					},
   786  				},
   787  			},
   788  			error: false,
   789  		},
   790  		{
   791  			name: "count filter single target ref new",
   792  			req: &pb.SearchRequest{
   793  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
   794  				Filters: &pb.Filters{
   795  					Operator:  pb.Filters_OPERATOR_LESS_THAN,
   796  					TestValue: &pb.Filters_ValueInt{ValueInt: 3},
   797  					Target:    &pb.FilterTarget{Target: &pb.FilterTarget_Count{Count: &pb.FilterReferenceCount{On: "ref"}}},
   798  				},
   799  			},
   800  			out: dto.GetParams{
   801  				ClassName: classname, Pagination: defaultPagination,
   802  				Properties:           defaultTestClassProps,
   803  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   804  				Filters: &filters.LocalFilter{
   805  					Root: &filters.Clause{
   806  						On: &filters.Path{
   807  							Class:    schema.ClassName(classname),
   808  							Property: "ref",
   809  						},
   810  						Operator: filters.OperatorLessThan,
   811  						Value:    &filters.Value{Value: 3, Type: schema.DataTypeInt},
   812  					},
   813  				},
   814  			},
   815  			error: false,
   816  		},
   817  		{
   818  			name: "count filter multi target ref old",
   819  			req: &pb.SearchRequest{
   820  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
   821  				Filters: &pb.Filters{
   822  					Operator:  pb.Filters_OPERATOR_LESS_THAN,
   823  					TestValue: &pb.Filters_ValueInt{ValueInt: 3},
   824  					On:        []string{"multiRef"},
   825  				},
   826  			},
   827  			out: dto.GetParams{
   828  				ClassName: classname, Pagination: defaultPagination,
   829  				Properties:           defaultTestClassProps,
   830  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   831  				Filters: &filters.LocalFilter{
   832  					Root: &filters.Clause{
   833  						On: &filters.Path{
   834  							Class:    schema.ClassName(classname),
   835  							Property: "multiRef",
   836  						},
   837  						Operator: filters.OperatorLessThan,
   838  						Value:    &filters.Value{Value: 3, Type: schema.DataTypeInt},
   839  					},
   840  				},
   841  			},
   842  			error: false,
   843  		},
   844  		{
   845  			name: "count filter multi target ref new",
   846  			req: &pb.SearchRequest{
   847  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
   848  				Filters: &pb.Filters{
   849  					Operator:  pb.Filters_OPERATOR_LESS_THAN,
   850  					TestValue: &pb.Filters_ValueInt{ValueInt: 3},
   851  					Target: &pb.FilterTarget{Target: &pb.FilterTarget_Count{Count: &pb.FilterReferenceCount{
   852  						On: "multiRef",
   853  					}}},
   854  				},
   855  			},
   856  			out: dto.GetParams{
   857  				ClassName: classname, Pagination: defaultPagination,
   858  				Properties:           defaultTestClassProps,
   859  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   860  				Filters: &filters.LocalFilter{
   861  					Root: &filters.Clause{
   862  						On: &filters.Path{
   863  							Class:    schema.ClassName(classname),
   864  							Property: "multiRef",
   865  						},
   866  						Operator: filters.OperatorLessThan,
   867  						Value:    &filters.Value{Value: 3, Type: schema.DataTypeInt},
   868  					},
   869  				},
   870  			},
   871  			error: false,
   872  		},
   873  		{
   874  			name: "length filter",
   875  			req: &pb.SearchRequest{
   876  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
   877  				Filters: &pb.Filters{
   878  					Operator:  pb.Filters_OPERATOR_LESS_THAN,
   879  					TestValue: &pb.Filters_ValueInt{ValueInt: 3},
   880  					On:        []string{"len(name)"},
   881  				},
   882  			},
   883  			out: dto.GetParams{
   884  				ClassName: classname, Pagination: defaultPagination,
   885  				Properties:           defaultTestClassProps,
   886  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   887  				Filters: &filters.LocalFilter{
   888  					Root: &filters.Clause{
   889  						On: &filters.Path{
   890  							Class:    schema.ClassName(classname),
   891  							Property: "len(name)",
   892  						},
   893  						Operator: filters.OperatorLessThan,
   894  						Value:    &filters.Value{Value: 3, Type: schema.DataTypeInt},
   895  					},
   896  				},
   897  			},
   898  			error: false,
   899  		},
   900  		{
   901  			name: "contains filter with int value on float prop",
   902  			req: &pb.SearchRequest{
   903  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
   904  				Filters: &pb.Filters{
   905  					Operator:  pb.Filters_OPERATOR_CONTAINS_ALL,
   906  					TestValue: &pb.Filters_ValueIntArray{ValueIntArray: &pb.IntArray{Values: []int64{3}}},
   907  					On:        []string{"floats"},
   908  				},
   909  			},
   910  			out: dto.GetParams{
   911  				ClassName: classname, Pagination: defaultPagination,
   912  				Properties:           defaultTestClassProps,
   913  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   914  				Filters: &filters.LocalFilter{
   915  					Root: &filters.Clause{
   916  						On: &filters.Path{
   917  							Class:    schema.ClassName(classname),
   918  							Property: "floats",
   919  						},
   920  						Operator: filters.ContainsAll,
   921  						Value:    &filters.Value{Value: []float64{3}, Type: schema.DataTypeNumber},
   922  					},
   923  				},
   924  			},
   925  			error: false,
   926  		},
   927  		{
   928  			name: "metadata filter id",
   929  			req: &pb.SearchRequest{
   930  				Collection: classname,
   931  				Filters: &pb.Filters{
   932  					Operator:  pb.Filters_OPERATOR_EQUAL,
   933  					TestValue: &pb.Filters_ValueText{ValueText: UUID4},
   934  					On:        []string{filters.InternalPropID},
   935  				},
   936  			},
   937  			out: dto.GetParams{
   938  				ClassName: classname, Pagination: defaultPagination,
   939  				Properties:           defaultTestClassProps,
   940  				AdditionalProperties: additional.Properties{NoProps: false},
   941  				Filters: &filters.LocalFilter{
   942  					Root: &filters.Clause{
   943  						On: &filters.Path{
   944  							Class:    schema.ClassName(classname),
   945  							Property: filters.InternalPropID,
   946  						},
   947  						Operator: filters.OperatorEqual,
   948  						Value:    &filters.Value{Value: UUID4, Type: schema.DataTypeText},
   949  					},
   950  				},
   951  			},
   952  			error: false,
   953  		},
   954  		{
   955  			name: "metadata filter time",
   956  			req: &pb.SearchRequest{
   957  				Collection: classname,
   958  				Filters: &pb.Filters{
   959  					Operator:  pb.Filters_OPERATOR_EQUAL,
   960  					TestValue: &pb.Filters_ValueText{ValueText: "2022-03-18T20:26:34.586-05:00"},
   961  					On:        []string{filters.InternalPropCreationTimeUnix},
   962  				},
   963  			},
   964  			out: dto.GetParams{
   965  				ClassName: classname, Pagination: defaultPagination,
   966  				Properties:           defaultTestClassProps,
   967  				AdditionalProperties: additional.Properties{NoProps: false},
   968  				Filters: &filters.LocalFilter{
   969  					Root: &filters.Clause{
   970  						On: &filters.Path{
   971  							Class:    schema.ClassName(classname),
   972  							Property: filters.InternalPropCreationTimeUnix,
   973  						},
   974  						Operator: filters.OperatorEqual,
   975  						Value:    &filters.Value{Value: "2022-03-18T20:26:34.586-05:00", Type: schema.DataTypeDate},
   976  					},
   977  				},
   978  			},
   979  			error: false,
   980  		},
   981  		{
   982  			name: "near text search",
   983  			req: &pb.SearchRequest{
   984  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
   985  				NearText: &pb.NearTextSearch{
   986  					Query:    []string{"first and", "second", "query"},
   987  					MoveTo:   &pb.NearTextSearch_Move{Force: 0.5, Concepts: []string{"first", "and second"}, Uuids: []string{UUID3, UUID4}},
   988  					MoveAway: &pb.NearTextSearch_Move{Force: 0.3, Concepts: []string{"second to last", "really last"}, Uuids: []string{UUID4}},
   989  				},
   990  			},
   991  			out: dto.GetParams{
   992  				ClassName: classname, Pagination: defaultPagination,
   993  				Properties:           defaultTestClassProps,
   994  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
   995  				ModuleParams: map[string]interface{}{
   996  					"nearText": &nearText2.NearTextParams{
   997  						Values: []string{"first and", "second", "query"},
   998  						MoveTo: nearText2.ExploreMove{
   999  							Force:  0.5,
  1000  							Values: []string{"first", "and second"},
  1001  							Objects: []nearText2.ObjectMove{
  1002  								{ID: UUID3, Beacon: crossref.NewLocalhost(classname, UUID3).String()},
  1003  								{ID: UUID4, Beacon: crossref.NewLocalhost(classname, UUID4).String()},
  1004  							},
  1005  						},
  1006  						MoveAwayFrom: nearText2.ExploreMove{
  1007  							Force:  0.3,
  1008  							Values: []string{"second to last", "really last"},
  1009  							Objects: []nearText2.ObjectMove{
  1010  								{ID: UUID4, Beacon: crossref.NewLocalhost(classname, UUID4).String()},
  1011  							},
  1012  						},
  1013  						Limit: 10, // default
  1014  					},
  1015  				},
  1016  			},
  1017  			error: false,
  1018  		},
  1019  		{
  1020  			name: "near text wrong uuid format",
  1021  			req: &pb.SearchRequest{
  1022  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
  1023  				NearText: &pb.NearTextSearch{
  1024  					Query:  []string{"first"},
  1025  					MoveTo: &pb.NearTextSearch_Move{Force: 0.5, Uuids: []string{"not a uuid"}},
  1026  				},
  1027  			},
  1028  			out:   dto.GetParams{},
  1029  			error: true,
  1030  		},
  1031  		{
  1032  			name: "near audio search",
  1033  			req: &pb.SearchRequest{
  1034  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
  1035  				NearAudio: &pb.NearAudioSearch{
  1036  					Audio: "audio file",
  1037  				},
  1038  			},
  1039  			out: dto.GetParams{
  1040  				ClassName: classname, Pagination: defaultPagination,
  1041  				Properties:           defaultTestClassProps,
  1042  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
  1043  				ModuleParams: map[string]interface{}{
  1044  					"nearAudio": &nearAudio.NearAudioParams{
  1045  						Audio: "audio file",
  1046  					},
  1047  				},
  1048  			},
  1049  			error: false,
  1050  		},
  1051  		{
  1052  			name: "near video search",
  1053  			req: &pb.SearchRequest{
  1054  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
  1055  				NearVideo: &pb.NearVideoSearch{
  1056  					Video: "video file",
  1057  				},
  1058  			},
  1059  			out: dto.GetParams{
  1060  				ClassName: classname, Pagination: defaultPagination,
  1061  				Properties:           defaultTestClassProps,
  1062  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
  1063  				ModuleParams: map[string]interface{}{
  1064  					"nearVideo": &nearVideo.NearVideoParams{
  1065  						Video: "video file",
  1066  					},
  1067  				},
  1068  			},
  1069  			error: false,
  1070  		},
  1071  		{
  1072  			name: "near image search",
  1073  			req: &pb.SearchRequest{
  1074  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
  1075  				NearImage: &pb.NearImageSearch{
  1076  					Image: "image file",
  1077  				},
  1078  			},
  1079  			out: dto.GetParams{
  1080  				ClassName: classname, Pagination: defaultPagination,
  1081  				Properties:           defaultTestClassProps,
  1082  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
  1083  				ModuleParams: map[string]interface{}{
  1084  					"nearImage": &nearImage.NearImageParams{
  1085  						Image: "image file",
  1086  					},
  1087  				},
  1088  			},
  1089  			error: false,
  1090  		},
  1091  		{
  1092  			name: "near depth search",
  1093  			req: &pb.SearchRequest{
  1094  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
  1095  				NearDepth: &pb.NearDepthSearch{
  1096  					Depth: "depth file",
  1097  				},
  1098  			},
  1099  			out: dto.GetParams{
  1100  				ClassName: classname, Pagination: defaultPagination,
  1101  				Properties:           defaultTestClassProps,
  1102  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
  1103  				ModuleParams: map[string]interface{}{
  1104  					"nearDepth": &nearDepth.NearDepthParams{
  1105  						Depth: "depth file",
  1106  					},
  1107  				},
  1108  			},
  1109  			error: false,
  1110  		},
  1111  		{
  1112  			name: "near thermal search",
  1113  			req: &pb.SearchRequest{
  1114  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
  1115  				NearThermal: &pb.NearThermalSearch{
  1116  					Thermal: "thermal file",
  1117  				},
  1118  			},
  1119  			out: dto.GetParams{
  1120  				ClassName: classname, Pagination: defaultPagination,
  1121  				Properties:           defaultTestClassProps,
  1122  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
  1123  				ModuleParams: map[string]interface{}{
  1124  					"nearThermal": &nearThermal.NearThermalParams{
  1125  						Thermal: "thermal file",
  1126  					},
  1127  				},
  1128  			},
  1129  			error: false,
  1130  		},
  1131  		{
  1132  			name: "near IMU search",
  1133  			req: &pb.SearchRequest{
  1134  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
  1135  				NearImu: &pb.NearIMUSearch{
  1136  					Imu: "IMU file",
  1137  				},
  1138  			},
  1139  			out: dto.GetParams{
  1140  				ClassName: classname, Pagination: defaultPagination,
  1141  				Properties:           defaultTestClassProps,
  1142  				AdditionalProperties: additional.Properties{Vector: true, NoProps: false},
  1143  				ModuleParams: map[string]interface{}{
  1144  					"nearIMU": &nearImu.NearIMUParams{
  1145  						IMU: "IMU file",
  1146  					},
  1147  				},
  1148  			},
  1149  			error: false,
  1150  		},
  1151  		{
  1152  			name: "Consistency",
  1153  			req: &pb.SearchRequest{
  1154  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
  1155  				ConsistencyLevel: &quorum,
  1156  			},
  1157  			out: dto.GetParams{
  1158  				ClassName: classname, Pagination: defaultPagination,
  1159  				Properties:            defaultTestClassProps,
  1160  				AdditionalProperties:  additional.Properties{Vector: true, NoProps: false},
  1161  				ReplicationProperties: &additional.ReplicationProperties{ConsistencyLevel: "QUORUM"},
  1162  			},
  1163  			error: false,
  1164  		},
  1165  		{
  1166  			name: "Generative",
  1167  			req: &pb.SearchRequest{
  1168  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
  1169  				Generative: &pb.GenerativeSearch{SingleResponsePrompt: someString1, GroupedResponseTask: someString2, GroupedProperties: []string{"one", "two"}},
  1170  			},
  1171  			out: dto.GetParams{
  1172  				ClassName: classname, Pagination: defaultPagination,
  1173  				Properties: defaultTestClassProps,
  1174  				AdditionalProperties: additional.Properties{
  1175  					Vector:  true,
  1176  					NoProps: false,
  1177  					ModuleParams: map[string]interface{}{
  1178  						"generate": &generate.Params{Prompt: &someString1, Task: &someString2, Properties: []string{"one", "two"}},
  1179  					},
  1180  				},
  1181  			},
  1182  			error: false,
  1183  		},
  1184  		{
  1185  			name: "Sort",
  1186  			req: &pb.SearchRequest{
  1187  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
  1188  				SortBy: []*pb.SortBy{{Ascending: false, Path: []string{"name"}}},
  1189  			},
  1190  			out: dto.GetParams{
  1191  				ClassName: classname, Pagination: defaultPagination,
  1192  				Properties: defaultTestClassProps,
  1193  				AdditionalProperties: additional.Properties{
  1194  					Vector:  true,
  1195  					NoProps: false,
  1196  				},
  1197  				Sort: []filters.Sort{{Order: "desc", Path: []string{"name"}}},
  1198  			},
  1199  			error: false,
  1200  		},
  1201  		{
  1202  			name: "Sort and vector search",
  1203  			req: &pb.SearchRequest{
  1204  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
  1205  				SortBy:     []*pb.SortBy{{Ascending: false, Path: []string{"name"}}},
  1206  				NearVector: &pb.NearVector{Vector: []float32{1, 2, 3}},
  1207  			},
  1208  			out:   dto.GetParams{},
  1209  			error: true,
  1210  		},
  1211  		{
  1212  			name: "group by",
  1213  			req: &pb.SearchRequest{
  1214  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
  1215  				GroupBy:    &pb.GroupBy{Path: []string{"name"}, NumberOfGroups: 2, ObjectsPerGroup: 3},
  1216  				NearVector: &pb.NearVector{Vector: []float32{1, 2, 3}},
  1217  			},
  1218  			out: dto.GetParams{
  1219  				ClassName: classname, Pagination: defaultPagination,
  1220  				Properties: defaultTestClassProps,
  1221  				AdditionalProperties: additional.Properties{
  1222  					Vector:  true,
  1223  					NoProps: false,
  1224  					Group:   true,
  1225  				},
  1226  				NearVector: &searchparams.NearVector{Vector: []float32{1, 2, 3}},
  1227  				GroupBy:    &searchparams.GroupBy{Groups: 2, ObjectsPerGroup: 3, Property: "name"},
  1228  			},
  1229  			error: false,
  1230  		},
  1231  		{
  1232  			name: "group by with too long path",
  1233  			req: &pb.SearchRequest{
  1234  				Collection: classname, Metadata: &pb.MetadataRequest{Vector: true},
  1235  				GroupBy:    &pb.GroupBy{Path: []string{"ref", "Class"}, NumberOfGroups: 2, ObjectsPerGroup: 3},
  1236  				NearVector: &pb.NearVector{Vector: []float32{1, 2, 3}},
  1237  			},
  1238  			out:   dto.GetParams{},
  1239  			error: true,
  1240  		},
  1241  		{
  1242  			name: "Object properties return",
  1243  			req: &pb.SearchRequest{
  1244  				Collection: objClass,
  1245  				Properties: &pb.PropertiesRequest{
  1246  					ObjectProperties: []*pb.ObjectPropertiesRequest{
  1247  						{
  1248  							PropName:            "something",
  1249  							PrimitiveProperties: []string{"name"},
  1250  							ObjectProperties: []*pb.ObjectPropertiesRequest{
  1251  								{
  1252  									PropName:            "else",
  1253  									PrimitiveProperties: []string{"name"},
  1254  								},
  1255  								{
  1256  									PropName:            "elses",
  1257  									PrimitiveProperties: []string{"name"},
  1258  								},
  1259  							},
  1260  						},
  1261  					},
  1262  				},
  1263  			},
  1264  			out: dto.GetParams{
  1265  				ClassName: objClass, Pagination: defaultPagination,
  1266  				Properties: search.SelectProperties{
  1267  					{
  1268  						Name: "something", IsPrimitive: false, IsObject: true,
  1269  						Props: search.SelectProperties{
  1270  							{Name: "name", IsPrimitive: true},
  1271  							{
  1272  								Name: "else", IsPrimitive: false, IsObject: true,
  1273  								Props: search.SelectProperties{{
  1274  									Name: "name", IsPrimitive: true,
  1275  								}},
  1276  							},
  1277  							{
  1278  								Name: "elses", IsPrimitive: false, IsObject: true,
  1279  								Props: search.SelectProperties{{
  1280  									Name: "name", IsPrimitive: true,
  1281  								}},
  1282  							},
  1283  						},
  1284  					},
  1285  				},
  1286  			},
  1287  		},
  1288  		{
  1289  			name: "Empty return values given nested",
  1290  			req:  &pb.SearchRequest{Collection: objClass},
  1291  			out: dto.GetParams{
  1292  				ClassName: objClass, Pagination: defaultPagination,
  1293  				Properties: search.SelectProperties{
  1294  					{
  1295  						Name: "something", IsPrimitive: false, IsObject: true,
  1296  						Props: search.SelectProperties{
  1297  							{Name: "name", IsPrimitive: true},
  1298  							{
  1299  								Name: "else", IsPrimitive: false, IsObject: true,
  1300  								Props: search.SelectProperties{{
  1301  									Name: "name", IsPrimitive: true,
  1302  								}},
  1303  							},
  1304  							{
  1305  								Name: "elses", IsPrimitive: false, IsObject: true,
  1306  								Props: search.SelectProperties{{
  1307  									Name: "name", IsPrimitive: true,
  1308  								}},
  1309  							},
  1310  						},
  1311  					},
  1312  				},
  1313  			},
  1314  			error: false,
  1315  		},
  1316  		{
  1317  			name: "No return values given nested with new default logic",
  1318  			req:  &pb.SearchRequest{Uses_123Api: true, Collection: objClass, Properties: &pb.PropertiesRequest{ReturnAllNonrefProperties: true}},
  1319  			out: dto.GetParams{
  1320  				ClassName: objClass, Pagination: defaultPagination,
  1321  				Properties: search.SelectProperties{
  1322  					{
  1323  						Name: "something", IsPrimitive: false, IsObject: true,
  1324  						Props: search.SelectProperties{
  1325  							{Name: "name", IsPrimitive: true},
  1326  							{
  1327  								Name: "else", IsPrimitive: false, IsObject: true,
  1328  								Props: search.SelectProperties{{
  1329  									Name: "name", IsPrimitive: true,
  1330  								}},
  1331  							},
  1332  							{
  1333  								Name: "elses", IsPrimitive: false, IsObject: true,
  1334  								Props: search.SelectProperties{{
  1335  									Name: "name", IsPrimitive: true,
  1336  								}},
  1337  							},
  1338  						},
  1339  					},
  1340  				},
  1341  			},
  1342  			error: false,
  1343  		},
  1344  		{
  1345  			name: "Rerank without query",
  1346  			req: &pb.SearchRequest{
  1347  				Collection: classname,
  1348  				Rerank:     &pb.Rerank{Property: someString1},
  1349  			},
  1350  			out: dto.GetParams{
  1351  				ClassName: classname, Pagination: defaultPagination,
  1352  				Properties: defaultTestClassProps,
  1353  				AdditionalProperties: additional.Properties{
  1354  					NoProps:      false,
  1355  					ModuleParams: map[string]interface{}{"rerank": &rank.Params{Property: &someString1}},
  1356  				},
  1357  			},
  1358  			error: false,
  1359  		},
  1360  		{
  1361  			name: "Rerank with query",
  1362  			req: &pb.SearchRequest{
  1363  				Collection: classname,
  1364  				Rerank:     &pb.Rerank{Property: someString1, Query: &someString2},
  1365  			},
  1366  			out: dto.GetParams{
  1367  				ClassName: classname, Pagination: defaultPagination,
  1368  				Properties: defaultTestClassProps,
  1369  				AdditionalProperties: additional.Properties{
  1370  					NoProps:      false,
  1371  					ModuleParams: map[string]interface{}{"rerank": &rank.Params{Property: &someString1, Query: &someString2}},
  1372  				},
  1373  			},
  1374  			error: false,
  1375  		},
  1376  	}
  1377  
  1378  	for _, tt := range tests {
  1379  		t.Run(tt.name, func(t *testing.T) {
  1380  			out, err := searchParamsFromProto(tt.req, scheme, &config.Config{QueryDefaults: config.QueryDefaults{Limit: 10}})
  1381  			if tt.error {
  1382  				require.NotNil(t, err)
  1383  			} else {
  1384  				require.Nil(t, err)
  1385  				// The order of vector names in slice is non-deterministic,
  1386  				// causing this test to be flaky. Sort first, no more flake
  1387  				sortNamedVecs(tt.out.AdditionalProperties.Vectors)
  1388  				sortNamedVecs(out.AdditionalProperties.Vectors)
  1389  				require.EqualValues(t, tt.out, out)
  1390  			}
  1391  		})
  1392  	}
  1393  }
  1394  
  1395  func sortNamedVecs(vecs []string) {
  1396  	sort.Slice(vecs, func(i, j int) bool {
  1397  		return vecs[i] < vecs[j]
  1398  	})
  1399  }