github.com/weaviate/weaviate@v1.24.6/test/acceptance/graphql_resolvers/local_aggregate_with_expected_failures.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 test 13 14 import ( 15 "strings" 16 "testing" 17 18 "github.com/stretchr/testify/assert" 19 "github.com/stretchr/testify/require" 20 "github.com/weaviate/weaviate/entities/models" 21 "github.com/weaviate/weaviate/entities/schema" 22 "github.com/weaviate/weaviate/test/helper" 23 graphqlhelper "github.com/weaviate/weaviate/test/helper/graphql" 24 ) 25 26 func aggregatesWithExpectedFailures(t *testing.T) { 27 t.Run("with nearVector, no certainty", func(t *testing.T) { 28 result := graphqlhelper.ErrorGraphQL(t, helper.RootAuth, ` 29 { 30 Aggregate{ 31 CustomVectorClass( 32 nearVector: { 33 vector: [1,0,0] 34 } 35 ){ 36 meta { 37 count 38 } 39 name { 40 topOccurrences { 41 occurs 42 value 43 } 44 type 45 count 46 } 47 } 48 } 49 } 50 `) 51 52 require.NotEmpty(t, result) 53 require.Len(t, result, 1) 54 assert.True(t, strings.Contains(result[0].Message, 55 "must provide certainty or objectLimit with vector search"), 56 "unexpected error message: %s", result[0].Message) 57 }) 58 59 t.Run("with nearObject, no certainty", func(t *testing.T) { 60 result := graphqlhelper.ErrorGraphQL(t, helper.RootAuth, ` 61 { 62 Aggregate{ 63 City( 64 nearObject: { 65 id: "9b9cbea5-e87e-4cd0-89af-e2f424fd52d6" 66 } 67 ){ 68 meta { 69 count 70 } 71 name { 72 topOccurrences { 73 occurs 74 value 75 } 76 type 77 count 78 } 79 } 80 } 81 } 82 `) 83 84 require.NotEmpty(t, result) 85 require.Len(t, result, 1) 86 assert.True(t, strings.Contains(result[0].Message, 87 "must provide certainty or objectLimit with vector search"), 88 "unexpected error message: %s", result[0].Message) 89 }) 90 91 t.Run("with nearText, no certainty", func(t *testing.T) { 92 result := graphqlhelper.ErrorGraphQL(t, helper.RootAuth, ` 93 { 94 Aggregate{ 95 City( 96 nearText: { 97 concepts: ["Amsterdam"] 98 } 99 ){ 100 meta { 101 count 102 } 103 name { 104 topOccurrences { 105 occurs 106 value 107 } 108 type 109 count 110 } 111 } 112 } 113 } 114 `) 115 116 require.NotEmpty(t, result) 117 require.Len(t, result, 1) 118 assert.True(t, strings.Contains(result[0].Message, 119 "must provide certainty or objectLimit with vector search"), 120 "unexpected error message: %s", result[0].Message) 121 }) 122 123 t.Run("with nearVector, where filter, no certainty", func(t *testing.T) { 124 result := graphqlhelper.ErrorGraphQL(t, helper.RootAuth, ` 125 { 126 Aggregate{ 127 CustomVectorClass( 128 where: { 129 valueText: "Mercedes", 130 operator: Equal, 131 path: ["name"] 132 } 133 nearVector: { 134 vector: [1,0,0] 135 } 136 ){ 137 meta { 138 count 139 } 140 name { 141 topOccurrences { 142 occurs 143 value 144 } 145 type 146 count 147 } 148 } 149 } 150 } 151 `) 152 153 require.NotEmpty(t, result) 154 require.Len(t, result, 1) 155 assert.True(t, strings.Contains(result[0].Message, 156 "must provide certainty or objectLimit with vector search"), 157 "unexpected error message: %s", result[0].Message) 158 }) 159 160 t.Run("with nearObject, where filter, no certainty", func(t *testing.T) { 161 result := graphqlhelper.ErrorGraphQL(t, helper.RootAuth, ` 162 { 163 Aggregate{ 164 City (where: { 165 valueBoolean: true, 166 operator: Equal, 167 path: ["isCapital"] 168 } 169 nearObject: { 170 id: "9b9cbea5-e87e-4cd0-89af-e2f424fd52d6" 171 } 172 ){ 173 meta { 174 count 175 } 176 isCapital { 177 count 178 percentageFalse 179 percentageTrue 180 totalFalse 181 totalTrue 182 type 183 } 184 population { 185 mean 186 count 187 maximum 188 minimum 189 sum 190 type 191 } 192 inCountry { 193 pointingTo 194 type 195 } 196 name { 197 topOccurrences { 198 occurs 199 value 200 } 201 type 202 count 203 } 204 } 205 } 206 } 207 `) 208 209 require.NotEmpty(t, result) 210 require.Len(t, result, 1) 211 assert.True(t, strings.Contains(result[0].Message, 212 "must provide certainty or objectLimit with vector search"), 213 "unexpected error message: %s", result[0].Message) 214 }) 215 216 t.Run("with nearText, where filter, no certainty", func(t *testing.T) { 217 result := graphqlhelper.ErrorGraphQL(t, helper.RootAuth, ` 218 { 219 Aggregate{ 220 City (where: { 221 valueBoolean: true, 222 operator: Equal, 223 path: ["isCapital"] 224 } 225 nearText: { 226 concepts: ["Amsterdam"] 227 } 228 ){ 229 meta { 230 count 231 } 232 isCapital { 233 count 234 percentageFalse 235 percentageTrue 236 totalFalse 237 totalTrue 238 type 239 } 240 population { 241 mean 242 count 243 maximum 244 minimum 245 sum 246 type 247 } 248 inCountry { 249 pointingTo 250 type 251 } 252 name { 253 topOccurrences { 254 occurs 255 value 256 } 257 type 258 count 259 } 260 } 261 } 262 } 263 `) 264 265 require.NotEmpty(t, result) 266 require.Len(t, result, 1) 267 assert.True(t, strings.Contains(result[0].Message, 268 "must provide certainty or objectLimit with vector search"), 269 "unexpected error message: %s", result[0].Message) 270 }) 271 272 t.Run("objectLimit passed with no nearMedia", func(t *testing.T) { 273 result := graphqlhelper.ErrorGraphQL(t, helper.RootAuth, ` 274 { 275 Aggregate{ 276 CustomVectorClass(objectLimit: 1){ 277 meta { 278 count 279 } 280 name { 281 topOccurrences { 282 occurs 283 value 284 } 285 type 286 count 287 } 288 } 289 } 290 } 291 `) 292 293 require.NotEmpty(t, result) 294 require.Len(t, result, 1) 295 assert.True(t, strings.Contains(result[0].Message, "objectLimit can only be used with a near<Media> or hybrid filter")) 296 }) 297 } 298 299 func exploreWithExpectedFailures(t *testing.T) { 300 t.Run("Explore called when classes have different distance configs", func(t *testing.T) { 301 className := "L2DistanceClass" 302 defer deleteObjectClass(t, className) 303 304 t.Run("create class configured with non-default distance type", func(t *testing.T) { 305 createObjectClass(t, &models.Class{ 306 Class: className, 307 ModuleConfig: map[string]interface{}{ 308 "text2vec-contextionary": map[string]interface{}{ 309 "vectorizeClassName": true, 310 }, 311 }, 312 VectorIndexConfig: map[string]interface{}{ 313 "distance": "l2-squared", 314 }, 315 Properties: []*models.Property{ 316 { 317 Name: "name", 318 DataType: schema.DataTypeText.PropString(), 319 Tokenization: models.PropertyTokenizationWhitespace, 320 }, 321 }, 322 }) 323 }) 324 325 t.Run("assert failure to Explore with mismatched distance types", func(t *testing.T) { 326 query := ` 327 { 328 Explore(nearVector: {vector:[1,1,1]}) { 329 distance 330 } 331 }` 332 333 result := graphqlhelper.ErrorGraphQL(t, helper.RootAuth, query) 334 assert.Len(t, result, 1) 335 336 errMsg := result[0].Message 337 assert.Contains(t, errMsg, "vector search across classes not possible") 338 assert.Contains(t, errMsg, "found different distance metrics") 339 assert.Contains(t, errMsg, "class 'L2DistanceClass' uses distance metric 'l2-squared'") 340 assert.Contains(t, errMsg, "class 'Airport' uses distance metric 'cosine'") 341 assert.Contains(t, errMsg, "class 'Person' uses distance metric 'cosine'") 342 assert.Contains(t, errMsg, "class 'ArrayClass' uses distance metric 'cosine'") 343 assert.Contains(t, errMsg, "class 'HasDateField' uses distance metric 'cosine'") 344 assert.Contains(t, errMsg, "class 'CustomVectorClass' uses distance metric 'cosine'") 345 assert.Contains(t, errMsg, "class 'RansomNote' uses distance metric 'cosine'") 346 assert.Contains(t, errMsg, "class 'MultiShard' uses distance metric 'cosine'") 347 assert.Contains(t, errMsg, "class 'Country' uses distance metric 'cosine'") 348 assert.Contains(t, errMsg, "class 'City' uses distance metric 'cosine'") 349 assert.Contains(t, errMsg, "class 'Company' uses distance metric 'cosine'") 350 assert.Contains(t, errMsg, "class 'Pizza' uses distance metric 'cosine'") 351 }) 352 }) 353 }