github.com/weaviate/weaviate@v1.24.6/test/acceptance/graphql_resolvers/local_aggregate_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 test
    13  
    14  import (
    15  	"encoding/json"
    16  	"fmt"
    17  	"strconv"
    18  	"testing"
    19  
    20  	"github.com/stretchr/testify/assert"
    21  	"github.com/stretchr/testify/require"
    22  	"github.com/weaviate/weaviate/entities/schema"
    23  	"github.com/weaviate/weaviate/test/helper"
    24  	graphqlhelper "github.com/weaviate/weaviate/test/helper/graphql"
    25  )
    26  
    27  // This test prevents a regression on the fix for
    28  // https://github.com/weaviate/weaviate/issues/824
    29  func localMeta_StringPropsNotSetEverywhere(t *testing.T) {
    30  	graphqlhelper.AssertGraphQL(t, helper.RootAuth, `
    31  		{
    32  			Aggregate {
    33  				City {
    34  					name {
    35  						topOccurrences {
    36  							occurs
    37  							value
    38  						}
    39  					}
    40  				}
    41  			}
    42  		}
    43  	`)
    44  }
    45  
    46  func localMetaWithWhereAndNearTextFilters(t *testing.T) {
    47  	t.Run("with distance", func(t *testing.T) {
    48  		result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, `
    49  		{
    50  			Aggregate{
    51  				City (where: {
    52  					valueBoolean: true,
    53  					operator: Equal,
    54  					path: ["isCapital"]
    55  				}
    56  				nearText: {
    57  					concepts: ["Amsterdam"]
    58  					distance: 0.2
    59  				}
    60  				){
    61  					meta {
    62  						count
    63  					}
    64  					isCapital {
    65  						count
    66  						percentageFalse
    67  						percentageTrue
    68  						totalFalse
    69  						totalTrue
    70  						type
    71  					}
    72  					population {
    73  						mean
    74  						count
    75  						maximum
    76  						minimum
    77  						sum
    78  						type
    79  					}
    80  					inCountry {
    81  						pointingTo
    82  						type
    83  					}
    84  					name {
    85  						topOccurrences {
    86  							occurs
    87  							value
    88  						}
    89  						type
    90  						count
    91  					}
    92  				}
    93  			}
    94  		}
    95  	`)
    96  
    97  		t.Run("meta count", func(t *testing.T) {
    98  			meta := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["meta"]
    99  			count := meta.(map[string]interface{})["count"]
   100  			expected := json.Number("1")
   101  			assert.Equal(t, expected, count)
   102  		})
   103  
   104  		t.Run("boolean props", func(t *testing.T) {
   105  			isCapital := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["isCapital"]
   106  			expected := map[string]interface{}{
   107  				"count":           json.Number("1"),
   108  				"percentageTrue":  json.Number("1"),
   109  				"percentageFalse": json.Number("0"),
   110  				"totalTrue":       json.Number("1"),
   111  				"totalFalse":      json.Number("0"),
   112  				"type":            "boolean",
   113  			}
   114  			assert.Equal(t, expected, isCapital)
   115  		})
   116  
   117  		t.Run("int/number props", func(t *testing.T) {
   118  			population := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["population"]
   119  			expected := map[string]interface{}{
   120  				"mean":    json.Number("1800000"),
   121  				"count":   json.Number("1"),
   122  				"maximum": json.Number("1800000"),
   123  				"minimum": json.Number("1800000"),
   124  				"sum":     json.Number("1800000"),
   125  				"type":    "int",
   126  			}
   127  			assert.Equal(t, expected, population)
   128  		})
   129  
   130  		t.Run("ref prop", func(t *testing.T) {
   131  			inCountry := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["inCountry"]
   132  			expected := map[string]interface{}{
   133  				"pointingTo": []interface{}{"Country"},
   134  				"type":       "cref",
   135  			}
   136  			assert.Equal(t, expected, inCountry)
   137  		})
   138  
   139  		t.Run("string prop", func(t *testing.T) {
   140  			name := result.Get("Aggregate", "City").
   141  				AsSlice()[0].(map[string]interface{})["name"].(map[string]interface{})
   142  			typeField := name["type"]
   143  			topOccurrences := name["topOccurrences"]
   144  
   145  			assert.Equal(t, schema.DataTypeText.String(), typeField)
   146  
   147  			expectedTopOccurrences := []interface{}{
   148  				map[string]interface{}{
   149  					"value":  "Amsterdam",
   150  					"occurs": json.Number("1"),
   151  				},
   152  			}
   153  			assert.ElementsMatch(t, expectedTopOccurrences, topOccurrences)
   154  		})
   155  	})
   156  
   157  	t.Run("with certainty", func(t *testing.T) {
   158  		result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, `
   159  		{
   160  			Aggregate{
   161  				City (where: {
   162  					valueBoolean: true,
   163  					operator: Equal,
   164  					path: ["isCapital"]
   165  				}
   166  				nearText: {
   167  					concepts: ["Amsterdam"]
   168  					certainty: 0.9
   169  				}
   170  				){
   171  					meta {
   172  						count
   173  					}
   174  					isCapital {
   175  						count
   176  						percentageFalse
   177  						percentageTrue
   178  						totalFalse
   179  						totalTrue
   180  						type
   181  					}
   182  					population {
   183  						mean
   184  						count
   185  						maximum
   186  						minimum
   187  						sum
   188  						type
   189  					}
   190  					inCountry {
   191  						pointingTo
   192  						type
   193  					}
   194  					name {
   195  						topOccurrences {
   196  							occurs
   197  							value
   198  						}
   199  						type
   200  						count
   201  					}
   202  				}
   203  			}
   204  		}`)
   205  
   206  		t.Run("meta count", func(t *testing.T) {
   207  			meta := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["meta"]
   208  			count := meta.(map[string]interface{})["count"]
   209  			expected := json.Number("1")
   210  			assert.Equal(t, expected, count)
   211  		})
   212  
   213  		t.Run("boolean props", func(t *testing.T) {
   214  			isCapital := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["isCapital"]
   215  			expected := map[string]interface{}{
   216  				"count":           json.Number("1"),
   217  				"percentageTrue":  json.Number("1"),
   218  				"percentageFalse": json.Number("0"),
   219  				"totalTrue":       json.Number("1"),
   220  				"totalFalse":      json.Number("0"),
   221  				"type":            "boolean",
   222  			}
   223  			assert.Equal(t, expected, isCapital)
   224  		})
   225  
   226  		t.Run("int/number props", func(t *testing.T) {
   227  			population := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["population"]
   228  			expected := map[string]interface{}{
   229  				"mean":    json.Number("1800000"),
   230  				"count":   json.Number("1"),
   231  				"maximum": json.Number("1800000"),
   232  				"minimum": json.Number("1800000"),
   233  				"sum":     json.Number("1800000"),
   234  				"type":    "int",
   235  			}
   236  			assert.Equal(t, expected, population)
   237  		})
   238  
   239  		t.Run("ref prop", func(t *testing.T) {
   240  			inCountry := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["inCountry"]
   241  			expected := map[string]interface{}{
   242  				"pointingTo": []interface{}{"Country"},
   243  				"type":       "cref",
   244  			}
   245  			assert.Equal(t, expected, inCountry)
   246  		})
   247  
   248  		t.Run("string prop", func(t *testing.T) {
   249  			name := result.Get("Aggregate", "City").
   250  				AsSlice()[0].(map[string]interface{})["name"].(map[string]interface{})
   251  			typeField := name["type"]
   252  			topOccurrences := name["topOccurrences"]
   253  
   254  			assert.Equal(t, schema.DataTypeText.String(), typeField)
   255  
   256  			expectedTopOccurrences := []interface{}{
   257  				map[string]interface{}{
   258  					"value":  "Amsterdam",
   259  					"occurs": json.Number("1"),
   260  				},
   261  			}
   262  			assert.ElementsMatch(t, expectedTopOccurrences, topOccurrences)
   263  		})
   264  	})
   265  }
   266  
   267  func localMetaWithWhereAndNearObjectFilters(t *testing.T) {
   268  	t.Run("with distance", func(t *testing.T) {
   269  		result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, `
   270  		{
   271  			Aggregate{
   272  				City (where: {
   273  					valueBoolean: true,
   274  					operator: Equal,
   275  					path: ["isCapital"]
   276  				}
   277  				nearObject: {
   278  					id: "9b9cbea5-e87e-4cd0-89af-e2f424fd52d6"
   279  					distance: 0.2
   280  				}
   281  				){
   282  					meta {
   283  						count
   284  					}
   285  					isCapital {
   286  						count
   287  						percentageFalse
   288  						percentageTrue
   289  						totalFalse
   290  						totalTrue
   291  						type
   292  					}
   293  					population {
   294  						mean
   295  						count
   296  						maximum
   297  						minimum
   298  						sum
   299  						type
   300  					}
   301  					inCountry {
   302  						pointingTo
   303  						type
   304  					}
   305  					name {
   306  						topOccurrences {
   307  							occurs
   308  							value
   309  						}
   310  						type
   311  						count
   312  					}
   313  				}
   314  			}
   315  		}`)
   316  
   317  		t.Run("meta count", func(t *testing.T) {
   318  			meta := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["meta"]
   319  			count := meta.(map[string]interface{})["count"]
   320  			expected := json.Number("1")
   321  			assert.Equal(t, expected, count)
   322  		})
   323  
   324  		t.Run("boolean props", func(t *testing.T) {
   325  			isCapital := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["isCapital"]
   326  			expected := map[string]interface{}{
   327  				"count":           json.Number("1"),
   328  				"percentageTrue":  json.Number("1"),
   329  				"percentageFalse": json.Number("0"),
   330  				"totalTrue":       json.Number("1"),
   331  				"totalFalse":      json.Number("0"),
   332  				"type":            "boolean",
   333  			}
   334  			assert.Equal(t, expected, isCapital)
   335  		})
   336  
   337  		t.Run("int/number props", func(t *testing.T) {
   338  			population := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["population"]
   339  			expected := map[string]interface{}{
   340  				"mean":    json.Number("3470000"),
   341  				"count":   json.Number("1"),
   342  				"maximum": json.Number("3470000"),
   343  				"minimum": json.Number("3470000"),
   344  				"sum":     json.Number("3470000"),
   345  				"type":    "int",
   346  			}
   347  			assert.Equal(t, expected, population)
   348  		})
   349  
   350  		t.Run("ref prop", func(t *testing.T) {
   351  			inCountry := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["inCountry"]
   352  			expected := map[string]interface{}{
   353  				"pointingTo": []interface{}{"Country"},
   354  				"type":       "cref",
   355  			}
   356  			assert.Equal(t, expected, inCountry)
   357  		})
   358  
   359  		t.Run("string prop", func(t *testing.T) {
   360  			name := result.Get("Aggregate", "City").
   361  				AsSlice()[0].(map[string]interface{})["name"].(map[string]interface{})
   362  			typeField := name["type"]
   363  			topOccurrences := name["topOccurrences"]
   364  
   365  			assert.Equal(t, schema.DataTypeText.String(), typeField)
   366  
   367  			expectedTopOccurrences := []interface{}{
   368  				map[string]interface{}{
   369  					"value":  "Berlin",
   370  					"occurs": json.Number("1"),
   371  				},
   372  			}
   373  			assert.ElementsMatch(t, expectedTopOccurrences, topOccurrences)
   374  		})
   375  	})
   376  
   377  	t.Run("with certainty", func(t *testing.T) {
   378  		result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, `
   379  		{
   380  			Aggregate{
   381  				City (where: {
   382  					valueBoolean: true,
   383  					operator: Equal,
   384  					path: ["isCapital"]
   385  				}
   386  				nearObject: {
   387  					id: "9b9cbea5-e87e-4cd0-89af-e2f424fd52d6"
   388  					certainty: 0.9
   389  				}
   390  				){
   391  					meta {
   392  						count
   393  					}
   394  					isCapital {
   395  						count
   396  						percentageFalse
   397  						percentageTrue
   398  						totalFalse
   399  						totalTrue
   400  						type
   401  					}
   402  					population {
   403  						mean
   404  						count
   405  						maximum
   406  						minimum
   407  						sum
   408  						type
   409  					}
   410  					inCountry {
   411  						pointingTo
   412  						type
   413  					}
   414  					name {
   415  						topOccurrences {
   416  							occurs
   417  							value
   418  						}
   419  						type
   420  						count
   421  					}
   422  				}
   423  			}
   424  		}`)
   425  
   426  		t.Run("meta count", func(t *testing.T) {
   427  			meta := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["meta"]
   428  			count := meta.(map[string]interface{})["count"]
   429  			expected := json.Number("1")
   430  			assert.Equal(t, expected, count)
   431  		})
   432  
   433  		t.Run("boolean props", func(t *testing.T) {
   434  			isCapital := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["isCapital"]
   435  			expected := map[string]interface{}{
   436  				"count":           json.Number("1"),
   437  				"percentageTrue":  json.Number("1"),
   438  				"percentageFalse": json.Number("0"),
   439  				"totalTrue":       json.Number("1"),
   440  				"totalFalse":      json.Number("0"),
   441  				"type":            "boolean",
   442  			}
   443  			assert.Equal(t, expected, isCapital)
   444  		})
   445  
   446  		t.Run("int/number props", func(t *testing.T) {
   447  			population := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["population"]
   448  			expected := map[string]interface{}{
   449  				"mean":    json.Number("3470000"),
   450  				"count":   json.Number("1"),
   451  				"maximum": json.Number("3470000"),
   452  				"minimum": json.Number("3470000"),
   453  				"sum":     json.Number("3470000"),
   454  				"type":    "int",
   455  			}
   456  			assert.Equal(t, expected, population)
   457  		})
   458  
   459  		t.Run("ref prop", func(t *testing.T) {
   460  			inCountry := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["inCountry"]
   461  			expected := map[string]interface{}{
   462  				"pointingTo": []interface{}{"Country"},
   463  				"type":       "cref",
   464  			}
   465  			assert.Equal(t, expected, inCountry)
   466  		})
   467  
   468  		t.Run("string prop", func(t *testing.T) {
   469  			name := result.Get("Aggregate", "City").
   470  				AsSlice()[0].(map[string]interface{})["name"].(map[string]interface{})
   471  			typeField := name["type"]
   472  			topOccurrences := name["topOccurrences"]
   473  
   474  			assert.Equal(t, schema.DataTypeText.String(), typeField)
   475  
   476  			expectedTopOccurrences := []interface{}{
   477  				map[string]interface{}{
   478  					"value":  "Berlin",
   479  					"occurs": json.Number("1"),
   480  				},
   481  			}
   482  			assert.ElementsMatch(t, expectedTopOccurrences, topOccurrences)
   483  		})
   484  	})
   485  }
   486  
   487  func localMetaWithNearVectorFilter(t *testing.T) {
   488  	t.Run("with distance", func(t *testing.T) {
   489  		result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, `
   490  		{
   491  			Aggregate{
   492  				CustomVectorClass(
   493  					nearVector: {
   494  						vector: [1,0,0]
   495  						distance: 0.0002
   496  					}
   497  				){
   498  					meta {
   499  						count
   500  					}
   501  					name {
   502  						topOccurrences {
   503  							occurs
   504  							value
   505  						}
   506  						type
   507  						count
   508  					}
   509  				}
   510  			}
   511  		}`)
   512  
   513  		t.Run("meta count", func(t *testing.T) {
   514  			meta := result.Get("Aggregate", "CustomVectorClass").AsSlice()[0].(map[string]interface{})["meta"]
   515  			count := meta.(map[string]interface{})["count"]
   516  			expected := json.Number("1")
   517  			assert.Equal(t, expected, count)
   518  		})
   519  
   520  		t.Run("string prop", func(t *testing.T) {
   521  			name := result.Get("Aggregate", "CustomVectorClass").
   522  				AsSlice()[0].(map[string]interface{})["name"].(map[string]interface{})
   523  			typeField := name["type"]
   524  			topOccurrences := name["topOccurrences"]
   525  
   526  			assert.Equal(t, schema.DataTypeText.String(), typeField)
   527  
   528  			expectedTopOccurrences := []interface{}{
   529  				map[string]interface{}{
   530  					"value":  "Mercedes",
   531  					"occurs": json.Number("1"),
   532  				},
   533  			}
   534  			assert.ElementsMatch(t, expectedTopOccurrences, topOccurrences)
   535  		})
   536  	})
   537  
   538  	t.Run("with certainty", func(t *testing.T) {
   539  		result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, `
   540  		{
   541  			Aggregate{
   542  				CustomVectorClass(
   543  					nearVector: {
   544  						vector: [1,0,0]
   545  						certainty: 0.9999
   546  					}
   547  				){
   548  					meta {
   549  						count
   550  					}
   551  					name {
   552  						topOccurrences {
   553  							occurs
   554  							value
   555  						}
   556  						type
   557  						count
   558  					}
   559  				}
   560  			}
   561  		}`)
   562  
   563  		t.Run("meta count", func(t *testing.T) {
   564  			meta := result.Get("Aggregate", "CustomVectorClass").AsSlice()[0].(map[string]interface{})["meta"]
   565  			count := meta.(map[string]interface{})["count"]
   566  			expected := json.Number("1")
   567  			assert.Equal(t, expected, count)
   568  		})
   569  
   570  		t.Run("string prop", func(t *testing.T) {
   571  			name := result.Get("Aggregate", "CustomVectorClass").
   572  				AsSlice()[0].(map[string]interface{})["name"].(map[string]interface{})
   573  			typeField := name["type"]
   574  			topOccurrences := name["topOccurrences"]
   575  
   576  			assert.Equal(t, schema.DataTypeText.String(), typeField)
   577  
   578  			expectedTopOccurrences := []interface{}{
   579  				map[string]interface{}{
   580  					"value":  "Mercedes",
   581  					"occurs": json.Number("1"),
   582  				},
   583  			}
   584  			assert.ElementsMatch(t, expectedTopOccurrences, topOccurrences)
   585  		})
   586  	})
   587  }
   588  
   589  func localMetaWithWhereAndNearVectorFilters(t *testing.T) {
   590  	t.Run("with distance", func(t *testing.T) {
   591  		t.Run("with expected results, low certainty", func(t *testing.T) {
   592  			result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, `
   593  			{
   594  				Aggregate {
   595  					CustomVectorClass(
   596  						where: {
   597  							valueText: "Ford"
   598  							operator: Equal
   599  							path: ["name"]
   600  						}
   601  						nearVector: {
   602  							vector: [1,0,0]
   603  							distance: 0.6
   604  						}
   605  					) {
   606  					meta {
   607  						count
   608  					}
   609  					name {
   610  						topOccurrences {
   611  							occurs
   612  							value
   613  						}
   614  						type
   615  						count
   616  					}
   617  				}
   618  				}
   619  			}
   620  		`)
   621  
   622  			require.NotNil(t, result)
   623  
   624  			agg := result.Result.(map[string]interface{})["Aggregate"].(map[string]interface{})
   625  			cls := agg["CustomVectorClass"].([]interface{})
   626  			require.Len(t, cls, 1)
   627  			name := cls[0].(map[string]interface{})["name"].(map[string]interface{})
   628  			topOcc := name["topOccurrences"].([]interface{})
   629  			require.Len(t, topOcc, 1)
   630  			val := topOcc[0].(map[string]interface{})["value"]
   631  			assert.Equal(t, "Ford", val)
   632  		})
   633  
   634  		t.Run("with no expected results, low distance", func(t *testing.T) {
   635  			result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, `
   636  			{
   637  				Aggregate {
   638  					CustomVectorClass(
   639  						where: {
   640  							valueText: "Ford"
   641  							operator: Equal
   642  							path: ["name"]
   643  						}
   644  						nearVector: {
   645  							vector: [1,0,0]
   646  							distance: 0.2
   647  						}
   648  					) {
   649  					meta {
   650  						count
   651  					}
   652  					name {
   653  						topOccurrences {
   654  							occurs
   655  							value
   656  						}
   657  						type
   658  						count
   659  					}
   660  				}
   661  				}
   662  			}
   663  		`)
   664  
   665  			require.NotNil(t, result)
   666  
   667  			agg := result.Result.(map[string]interface{})["Aggregate"].(map[string]interface{})
   668  			cls := agg["CustomVectorClass"].([]interface{})
   669  			require.Len(t, cls, 1)
   670  			name := cls[0].(map[string]interface{})["name"].(map[string]interface{})
   671  			topOcc := name["topOccurrences"].([]interface{})
   672  			require.Len(t, topOcc, 0)
   673  		})
   674  
   675  		t.Run("with expected results, low distance", func(t *testing.T) {
   676  			result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, `
   677  			{
   678  				Aggregate {
   679  					CustomVectorClass(
   680  						where: {
   681  							valueText: "Mercedes"
   682  							operator: Equal
   683  							path: ["name"]
   684  						}
   685  						nearVector: {
   686  							vector: [1,0,0]
   687  							distance: 0.1
   688  						}
   689  					) {
   690  					meta {
   691  						count
   692  					}
   693  					name {
   694  						topOccurrences {
   695  							occurs
   696  							value
   697  						}
   698  						type
   699  						count
   700  					}
   701  				}
   702  				}
   703  			}`)
   704  
   705  			require.NotNil(t, result)
   706  
   707  			agg := result.Result.(map[string]interface{})["Aggregate"].(map[string]interface{})
   708  			cls := agg["CustomVectorClass"].([]interface{})
   709  			require.Len(t, cls, 1)
   710  			name := cls[0].(map[string]interface{})["name"].(map[string]interface{})
   711  			topOcc := name["topOccurrences"].([]interface{})
   712  			require.Len(t, topOcc, 1)
   713  			val := topOcc[0].(map[string]interface{})["value"]
   714  			assert.Equal(t, "Mercedes", val)
   715  		})
   716  	})
   717  
   718  	t.Run("with certainty", func(t *testing.T) {
   719  		t.Run("with expected results, low certainty", func(t *testing.T) {
   720  			result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, `
   721  			{
   722  				Aggregate {
   723  					CustomVectorClass(
   724  						where: {
   725  							valueText: "Ford"
   726  							operator: Equal
   727  							path: ["name"]
   728  						}
   729  						nearVector: {
   730  							vector: [1,0,0]
   731  							certainty: 0.7
   732  						}
   733  					) {
   734  					meta {
   735  						count
   736  					}
   737  					name {
   738  						topOccurrences {
   739  							occurs
   740  							value
   741  						}
   742  						type
   743  						count
   744  					}
   745  				}
   746  				}
   747  			}
   748  		`)
   749  
   750  			require.NotNil(t, result)
   751  
   752  			agg := result.Result.(map[string]interface{})["Aggregate"].(map[string]interface{})
   753  			cls := agg["CustomVectorClass"].([]interface{})
   754  			require.Len(t, cls, 1)
   755  			name := cls[0].(map[string]interface{})["name"].(map[string]interface{})
   756  			topOcc := name["topOccurrences"].([]interface{})
   757  			require.Len(t, topOcc, 1)
   758  			val := topOcc[0].(map[string]interface{})["value"]
   759  			assert.Equal(t, "Ford", val)
   760  		})
   761  
   762  		t.Run("with no expected results, high certainty", func(t *testing.T) {
   763  			result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, `
   764  			{
   765  				Aggregate {
   766  					CustomVectorClass(
   767  						where: {
   768  							valueText: "Ford"
   769  							operator: Equal
   770  							path: ["name"]
   771  						}
   772  						nearVector: {
   773  							vector: [1,0,0]
   774  							certainty: 0.9
   775  						}
   776  					) {
   777  					meta {
   778  						count
   779  					}
   780  					name {
   781  						topOccurrences {
   782  							occurs
   783  							value
   784  						}
   785  						type
   786  						count
   787  					}
   788  				}
   789  				}
   790  			}
   791  		`)
   792  
   793  			require.NotNil(t, result)
   794  
   795  			agg := result.Result.(map[string]interface{})["Aggregate"].(map[string]interface{})
   796  			cls := agg["CustomVectorClass"].([]interface{})
   797  			require.Len(t, cls, 1)
   798  			name := cls[0].(map[string]interface{})["name"].(map[string]interface{})
   799  			topOcc := name["topOccurrences"].([]interface{})
   800  			require.Len(t, topOcc, 0)
   801  		})
   802  
   803  		t.Run("with expected results, high certainty", func(t *testing.T) {
   804  			result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, `
   805  			{
   806  				Aggregate {
   807  					CustomVectorClass(
   808  						where: {
   809  							valueText: "Mercedes"
   810  							operator: Equal
   811  							path: ["name"]
   812  						}
   813  						nearVector: {
   814  							vector: [1,0,0]
   815  							certainty: 0.9
   816  						}
   817  					) {
   818  					meta {
   819  						count
   820  					}
   821  					name {
   822  						topOccurrences {
   823  							occurs
   824  							value
   825  						}
   826  						type
   827  						count
   828  					}
   829  				}
   830  				}
   831  			}
   832  		`)
   833  
   834  			require.NotNil(t, result)
   835  
   836  			agg := result.Result.(map[string]interface{})["Aggregate"].(map[string]interface{})
   837  			cls := agg["CustomVectorClass"].([]interface{})
   838  			require.Len(t, cls, 1)
   839  			name := cls[0].(map[string]interface{})["name"].(map[string]interface{})
   840  			topOcc := name["topOccurrences"].([]interface{})
   841  			require.Len(t, topOcc, 1)
   842  			val := topOcc[0].(map[string]interface{})["value"]
   843  			assert.Equal(t, "Mercedes", val)
   844  		})
   845  	})
   846  }
   847  
   848  func localMetaWithWhereGroupByNearMediaFilters(t *testing.T) {
   849  	t.Run("with nearObject", func(t *testing.T) {
   850  		query := `
   851  			{
   852  				Aggregate {
   853  					Company
   854  					(
   855  						groupBy: "name"
   856  						nearObject: {id: "cfa3b21e-ca4f-4db7-a432-7fc6a23c534d", certainty: 0.99}
   857  					) 
   858  					{
   859  						groupedBy {
   860  							value
   861  					  	}
   862  						meta {
   863  							count
   864  						}
   865  					}
   866  				}
   867  			}`
   868  
   869  		expected := map[string]interface{}{
   870  			"Aggregate": map[string]interface{}{
   871  				"Company": []interface{}{
   872  					map[string]interface{}{
   873  						"groupedBy": map[string]interface{}{
   874  							"value": "Microsoft Inc.",
   875  						},
   876  						"meta": map[string]interface{}{
   877  							"count": json.Number("1"),
   878  						},
   879  					},
   880  				},
   881  			},
   882  		}
   883  
   884  		result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, query).Result
   885  		assert.EqualValues(t, expected, result)
   886  	})
   887  
   888  	t.Run("with nearText", func(t *testing.T) {
   889  		t.Run("with distance", func(t *testing.T) {
   890  			result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, `
   891  			{
   892  				Aggregate{
   893  					City (
   894  					groupBy: "population"
   895  					where: {
   896  						valueBoolean: true,
   897  						operator: Equal,
   898  						path: ["isCapital"]
   899  					}
   900  					nearText: {
   901  						concepts: ["Amsterdam"]
   902  						distance: 0.2
   903  					}
   904  					){
   905  						meta {
   906  							count
   907  						}
   908  						groupedBy {
   909  							value
   910  						}
   911  					}
   912  				}
   913  			}
   914  		`)
   915  
   916  			expected := map[string]interface{}{
   917  				"Aggregate": map[string]interface{}{
   918  					"City": []interface{}{
   919  						map[string]interface{}{
   920  							"groupedBy": map[string]interface{}{
   921  								"value": "1.8e+06",
   922  							},
   923  							"meta": map[string]interface{}{
   924  								"count": json.Number("1"),
   925  							},
   926  						},
   927  					},
   928  				},
   929  			}
   930  
   931  			assert.EqualValues(t, expected, result.Result)
   932  		})
   933  
   934  		t.Run("with certainty", func(t *testing.T) {
   935  			result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, `
   936  			{
   937  				Aggregate{
   938  					City (
   939  					groupBy: "population"
   940  					where: {
   941  						valueBoolean: true,
   942  						operator: Equal,
   943  						path: ["isCapital"]
   944  					}
   945  					nearText: {
   946  						concepts: ["Amsterdam"]
   947  						certainty: 0.9
   948  					}
   949  					){
   950  						meta {
   951  							count
   952  						}
   953  						groupedBy {
   954  							value
   955  						}
   956  					}
   957  				}
   958  			}
   959  		`)
   960  
   961  			expected := map[string]interface{}{
   962  				"Aggregate": map[string]interface{}{
   963  					"City": []interface{}{
   964  						map[string]interface{}{
   965  							"groupedBy": map[string]interface{}{
   966  								"value": "1.8e+06",
   967  							},
   968  							"meta": map[string]interface{}{
   969  								"count": json.Number("1"),
   970  							},
   971  						},
   972  					},
   973  				},
   974  			}
   975  
   976  			assert.EqualValues(t, expected, result.Result)
   977  		})
   978  	})
   979  
   980  	t.Run("with nearVector", func(t *testing.T) {
   981  		getQuery := `
   982  			{
   983  				Get {
   984  					Company(where: {
   985  						path: ["name"]
   986  						operator: Equal
   987  						valueText: "Google Inc."
   988  					})
   989  					{
   990  						_additional {
   991  							vector
   992  						}
   993  					}
   994  				}
   995  			}`
   996  
   997  		vectorResult := graphqlhelper.AssertGraphQL(t, helper.RootAuth, getQuery).
   998  			Get("Get", "Company").
   999  			AsSlice()[0].(map[string]interface{})["_additional"].(map[string]interface{})["vector"].([]interface{})
  1000  
  1001  		vector := make([]float32, len(vectorResult))
  1002  		for i, ifc := range vectorResult {
  1003  			val, err := strconv.ParseFloat(ifc.(json.Number).String(), 32)
  1004  			require.Nil(t, err)
  1005  			vector[i] = float32(val)
  1006  		}
  1007  
  1008  		aggQuery := fmt.Sprintf(`
  1009  			{
  1010  				Aggregate {
  1011  					Company
  1012  					(
  1013  						groupBy: "name"
  1014  						nearVector: {vector: %+v, certainty: 0.99}
  1015  					)
  1016  					{
  1017  						groupedBy {
  1018  							value
  1019  						}
  1020  						meta {
  1021  							count
  1022  						}
  1023  					}
  1024  				}
  1025  			}
  1026  		`, vector)
  1027  
  1028  		aggResult := graphqlhelper.AssertGraphQL(t, helper.RootAuth, aggQuery).Result
  1029  
  1030  		expected := map[string]interface{}{
  1031  			"Aggregate": map[string]interface{}{
  1032  				"Company": []interface{}{
  1033  					map[string]interface{}{
  1034  						"groupedBy": map[string]interface{}{
  1035  							"value": "Google Inc.",
  1036  						},
  1037  						"meta": map[string]interface{}{
  1038  							"count": json.Number("1"),
  1039  						},
  1040  					},
  1041  				},
  1042  			},
  1043  		}
  1044  
  1045  		assert.EqualValues(t, expected, aggResult)
  1046  	})
  1047  }
  1048  
  1049  func localMetaWithObjectLimit(t *testing.T) {
  1050  	t.Run("with nearObject and distance", func(t *testing.T) {
  1051  		objectLimit := 1
  1052  		result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, fmt.Sprintf(`
  1053  			{
  1054  				Aggregate{
  1055  					City (
  1056  						objectLimit: %d
  1057  						nearObject: {
  1058  							id: "9b9cbea5-e87e-4cd0-89af-e2f424fd52d6"
  1059  							distance: 0.3
  1060  						}
  1061  					){
  1062  						meta {
  1063  							count
  1064  						}
  1065  					}
  1066  				}
  1067  			}
  1068  		`, objectLimit))
  1069  
  1070  		t.Run("validate objectLimit functions as expected", func(t *testing.T) {
  1071  			res := result.Get("Aggregate", "City").AsSlice()
  1072  			require.Len(t, res, 1)
  1073  			meta := res[0].(map[string]interface{})["meta"]
  1074  			count := meta.(map[string]interface{})["count"]
  1075  			assert.Equal(t, json.Number(fmt.Sprint(objectLimit)), count)
  1076  		})
  1077  	})
  1078  
  1079  	t.Run("with nearObject and certainty", func(t *testing.T) {
  1080  		objectLimit := 1
  1081  		result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, fmt.Sprintf(`
  1082  			{
  1083  				Aggregate{
  1084  					City (
  1085  						objectLimit: %d
  1086  						nearObject: {
  1087  							id: "9b9cbea5-e87e-4cd0-89af-e2f424fd52d6"
  1088  							certainty: 0.7
  1089  						}
  1090  					){
  1091  						meta {
  1092  							count
  1093  						}
  1094  					}
  1095  				}
  1096  			}
  1097  		`, objectLimit))
  1098  
  1099  		t.Run("validate objectLimit functions as expected", func(t *testing.T) {
  1100  			res := result.Get("Aggregate", "City").AsSlice()
  1101  			require.Len(t, res, 1)
  1102  			meta := res[0].(map[string]interface{})["meta"]
  1103  			count := meta.(map[string]interface{})["count"]
  1104  			assert.Equal(t, json.Number(fmt.Sprint(objectLimit)), count)
  1105  		})
  1106  	})
  1107  
  1108  	t.Run("with nearObject and no certainty", func(t *testing.T) {
  1109  		objectLimit := 2
  1110  		result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, fmt.Sprintf(`
  1111  			{
  1112  				Aggregate{
  1113  					City (
  1114  						objectLimit: %d
  1115  						nearObject: {
  1116  							id: "9b9cbea5-e87e-4cd0-89af-e2f424fd52d6"
  1117  						}
  1118  					){
  1119  						meta {
  1120  							count
  1121  						}
  1122  					}
  1123  				}
  1124  			}
  1125  		`, objectLimit))
  1126  
  1127  		t.Run("validate objectLimit functions as expected", func(t *testing.T) {
  1128  			res := result.Get("Aggregate", "City").AsSlice()
  1129  			require.Len(t, res, 1)
  1130  			meta := res[0].(map[string]interface{})["meta"]
  1131  			count := meta.(map[string]interface{})["count"]
  1132  			assert.Equal(t, json.Number(fmt.Sprint(objectLimit)), count)
  1133  		})
  1134  	})
  1135  
  1136  	t.Run("with nearObject and very high distance, no objectLimit", func(t *testing.T) {
  1137  		result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, `
  1138  			{
  1139  				Aggregate {
  1140     				RansomNote(
  1141       					nearText: {
  1142  							concepts: ["abc"]
  1143  							distance: 1.9998
  1144       					}
  1145     				) {
  1146  					  meta {
  1147  						count
  1148  					  }
  1149    					}
  1150   				}
  1151  			}
  1152  		`)
  1153  
  1154  		t.Run("validate nearMedia runs unlimited without objectLimit", func(t *testing.T) {
  1155  			res := result.Get("Aggregate", "RansomNote").AsSlice()
  1156  			require.Len(t, res, 1)
  1157  			meta := res[0].(map[string]interface{})["meta"]
  1158  			count := meta.(map[string]interface{})["count"]
  1159  			assert.Equal(t, json.Number("500"), count)
  1160  		})
  1161  	})
  1162  
  1163  	t.Run("with nearObject and very low certainty, no objectLimit", func(t *testing.T) {
  1164  		result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, `
  1165  			{
  1166  				Aggregate {
  1167     				RansomNote(
  1168       					nearText: {
  1169  							concepts: ["abc"]
  1170  							certainty: 0.0001
  1171       					}
  1172     				) {
  1173  					  meta {
  1174  						count
  1175  					  }
  1176    					}
  1177   				}
  1178  			}
  1179  		`)
  1180  
  1181  		t.Run("validate nearMedia runs unlimited without objectLimit", func(t *testing.T) {
  1182  			res := result.Get("Aggregate", "RansomNote").AsSlice()
  1183  			require.Len(t, res, 1)
  1184  			meta := res[0].(map[string]interface{})["meta"]
  1185  			count := meta.(map[string]interface{})["count"]
  1186  			assert.Equal(t, json.Number("500"), count)
  1187  		})
  1188  	})
  1189  
  1190  	t.Run("with nearObject and low distance (few results), high objectLimit", func(t *testing.T) {
  1191  		result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, `
  1192  			{
  1193  				Aggregate {
  1194     				RansomNote(
  1195       					nearText: {
  1196  							concepts: ["abc"]
  1197  							distance: 0.6 # should return about 6 elements
  1198       					}
  1199  						  objectLimit:100,
  1200     				) {
  1201  					  meta {
  1202  						count
  1203  					  }
  1204    					}
  1205   				}
  1206  			}
  1207  		`)
  1208  
  1209  		t.Run("validate fewer than objectLimit elements are returned", func(t *testing.T) {
  1210  			res := result.Get("Aggregate", "RansomNote").AsSlice()
  1211  			require.Len(t, res, 1)
  1212  			meta := res[0].(map[string]interface{})["meta"]
  1213  			count := meta.(map[string]interface{})["count"]
  1214  			countParsed, err := count.(json.Number).Int64()
  1215  			require.Nil(t, err)
  1216  			assert.Less(t, countParsed, int64(100))
  1217  		})
  1218  	})
  1219  
  1220  	t.Run("with nearObject and high certainty (few results), high objectLimit", func(t *testing.T) {
  1221  		result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, `
  1222  			{
  1223  				Aggregate {
  1224     				RansomNote(
  1225       					nearText: {
  1226  							concepts: ["abc"]
  1227  							certainty: 0.7 # should return about 6 elements
  1228       					}
  1229  						  objectLimit:100,
  1230     				) {
  1231  					  meta {
  1232  						count
  1233  					  }
  1234    					}
  1235   				}
  1236  			}
  1237  		`)
  1238  
  1239  		t.Run("validate fewer than objectLimit elements are returned", func(t *testing.T) {
  1240  			res := result.Get("Aggregate", "RansomNote").AsSlice()
  1241  			require.Len(t, res, 1)
  1242  			meta := res[0].(map[string]interface{})["meta"]
  1243  			count := meta.(map[string]interface{})["count"]
  1244  			countParsed, err := count.(json.Number).Int64()
  1245  			require.Nil(t, err)
  1246  			assert.Less(t, countParsed, int64(100))
  1247  		})
  1248  	})
  1249  
  1250  	t.Run("with nearText and no distance/certainty, where filter and groupBy", func(t *testing.T) {
  1251  		objectLimit := 4
  1252  		result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, fmt.Sprintf(`
  1253  			{
  1254  				Aggregate {
  1255  					Company (
  1256  						groupBy: ["name"]
  1257  						where: {
  1258  							valueText: "Apple*",
  1259  							operator: Like,
  1260  							path: ["name"]
  1261  						}
  1262  						objectLimit: %d
  1263  						nearText: {
  1264  							concepts: ["Apple"]
  1265  							certainty: 0.5
  1266  						}
  1267  					){
  1268  						meta {
  1269  							count
  1270  						}
  1271  						groupedBy {
  1272          					value
  1273  						}
  1274  					}
  1275  				}
  1276  			}
  1277  		`, objectLimit))
  1278  
  1279  		expected := []interface{}{
  1280  			map[string]interface{}{
  1281  				"groupedBy": map[string]interface{}{
  1282  					"value": "Apple Incorporated",
  1283  				},
  1284  				"meta": map[string]interface{}{
  1285  					"count": json.Number("1"),
  1286  				},
  1287  			},
  1288  			map[string]interface{}{
  1289  				"groupedBy": map[string]interface{}{
  1290  					"value": "Apple Inc.",
  1291  				},
  1292  				"meta": map[string]interface{}{
  1293  					"count": json.Number("1"),
  1294  				},
  1295  			},
  1296  			map[string]interface{}{
  1297  				"groupedBy": map[string]interface{}{
  1298  					"value": "Apple",
  1299  				},
  1300  				"meta": map[string]interface{}{
  1301  					"count": json.Number("1"),
  1302  				},
  1303  			},
  1304  		}
  1305  
  1306  		companies := result.Get("Aggregate", "Company").Result.([]interface{})
  1307  		for _, company := range companies {
  1308  			assert.Contains(t, expected, company)
  1309  		}
  1310  	})
  1311  
  1312  	t.Run("with nearObject and certainty, where filter", func(t *testing.T) {
  1313  		objectLimit := 1
  1314  		result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, fmt.Sprintf(`
  1315  			{
  1316  				Aggregate{
  1317  					City (
  1318  						where: {
  1319  							valueBoolean: true,
  1320  							operator: Equal,
  1321  							path: ["isCapital"]
  1322  						}
  1323  						objectLimit: %d
  1324  						nearObject: {
  1325  							id: "9b9cbea5-e87e-4cd0-89af-e2f424fd52d6"
  1326  						}
  1327  					){
  1328  						meta {
  1329  							count
  1330  						}
  1331  					}
  1332  				}
  1333  			}
  1334  		`, objectLimit))
  1335  
  1336  		t.Run("validate objectLimit functions as expected", func(t *testing.T) {
  1337  			res := result.Get("Aggregate", "City").AsSlice()
  1338  			require.Len(t, res, 1)
  1339  			meta := res[0].(map[string]interface{})["meta"]
  1340  			count := meta.(map[string]interface{})["count"]
  1341  			assert.Equal(t, json.Number(fmt.Sprint(objectLimit)), count)
  1342  		})
  1343  	})
  1344  }
  1345  
  1346  func aggregatesOnDateFields(t *testing.T) {
  1347  	t.Run("without grouping", func(t *testing.T) {
  1348  		query := `
  1349  		{
  1350  			Aggregate {
  1351  				HasDateField {
  1352  					timestamp {
  1353  						count
  1354  						minimum
  1355  						maximum
  1356  						median
  1357  					}
  1358  				}
  1359  			}
  1360  		}`
  1361  		result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, query).Get("Aggregate", "HasDateField").AsSlice()
  1362  		assert.Len(t, result, 1)
  1363  
  1364  		expected := []interface{}{
  1365  			map[string]interface{}{
  1366  				"timestamp": map[string]interface{}{
  1367  					"count":   json.Number("10"),
  1368  					"maximum": "2022-06-16T22:19:11.837473Z",
  1369  					"median":  "2022-06-16T22:19:06.1449075Z",
  1370  					"minimum": "2022-06-16T22:18:59.640162Z",
  1371  				},
  1372  			},
  1373  		}
  1374  		assert.Equal(t, expected, result)
  1375  	})
  1376  
  1377  	t.Run("with grouping on a unique field", func(t *testing.T) {
  1378  		query := `
  1379  		{
  1380  			Aggregate {
  1381  				HasDateField 
  1382  				(
  1383  					groupBy: "unique"
  1384  				)
  1385  				{
  1386  					timestamp {
  1387  						count
  1388  						minimum
  1389  						maximum
  1390  						median
  1391  						mode
  1392  					}
  1393  				}
  1394  			}
  1395  		}`
  1396  
  1397  		result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, query).Get("Aggregate", "HasDateField").AsSlice()
  1398  		assert.Len(t, result, 10)
  1399  
  1400  		expected := []interface{}{
  1401  			map[string]interface{}{
  1402  				"timestamp": map[string]interface{}{
  1403  					"count":   json.Number("1"),
  1404  					"maximum": "2022-06-16T22:19:05.894857Z",
  1405  					"median":  "2022-06-16T22:19:05.894857Z",
  1406  					"minimum": "2022-06-16T22:19:05.894857Z",
  1407  					"mode":    "2022-06-16T22:19:05.894857Z",
  1408  				},
  1409  			},
  1410  			map[string]interface{}{
  1411  				"timestamp": map[string]interface{}{
  1412  					"count":   json.Number("1"),
  1413  					"maximum": "2022-06-16T22:19:08.112395Z",
  1414  					"median":  "2022-06-16T22:19:08.112395Z",
  1415  					"minimum": "2022-06-16T22:19:08.112395Z",
  1416  					"mode":    "2022-06-16T22:19:08.112395Z",
  1417  				},
  1418  			},
  1419  			map[string]interface{}{
  1420  				"timestamp": map[string]interface{}{
  1421  					"count":   json.Number("1"),
  1422  					"maximum": "2022-06-16T22:19:03.495596Z",
  1423  					"median":  "2022-06-16T22:19:03.495596Z",
  1424  					"minimum": "2022-06-16T22:19:03.495596Z",
  1425  					"mode":    "2022-06-16T22:19:03.495596Z",
  1426  				},
  1427  			},
  1428  			map[string]interface{}{
  1429  				"timestamp": map[string]interface{}{
  1430  					"count":   json.Number("1"),
  1431  					"maximum": "2022-06-16T22:19:07.589828Z",
  1432  					"median":  "2022-06-16T22:19:07.589828Z",
  1433  					"minimum": "2022-06-16T22:19:07.589828Z",
  1434  					"mode":    "2022-06-16T22:19:07.589828Z",
  1435  				},
  1436  			},
  1437  			map[string]interface{}{
  1438  				"timestamp": map[string]interface{}{
  1439  					"count":   json.Number("1"),
  1440  					"maximum": "2022-06-16T22:19:06.394958Z",
  1441  					"median":  "2022-06-16T22:19:06.394958Z",
  1442  					"minimum": "2022-06-16T22:19:06.394958Z",
  1443  					"mode":    "2022-06-16T22:19:06.394958Z",
  1444  				},
  1445  			},
  1446  			map[string]interface{}{
  1447  				"timestamp": map[string]interface{}{
  1448  					"count":   json.Number("1"),
  1449  					"maximum": "2022-06-16T22:19:11.837473Z",
  1450  					"median":  "2022-06-16T22:19:11.837473Z",
  1451  					"minimum": "2022-06-16T22:19:11.837473Z",
  1452  					"mode":    "2022-06-16T22:19:11.837473Z",
  1453  				},
  1454  			},
  1455  			map[string]interface{}{
  1456  				"timestamp": map[string]interface{}{
  1457  					"count":   json.Number("1"),
  1458  					"maximum": "2022-06-16T22:18:59.640162Z",
  1459  					"median":  "2022-06-16T22:18:59.640162Z",
  1460  					"minimum": "2022-06-16T22:18:59.640162Z",
  1461  					"mode":    "2022-06-16T22:18:59.640162Z",
  1462  				},
  1463  			},
  1464  			map[string]interface{}{
  1465  				"timestamp": map[string]interface{}{
  1466  					"count":   json.Number("1"),
  1467  					"maximum": "2022-06-16T22:19:01.495967Z",
  1468  					"median":  "2022-06-16T22:19:01.495967Z",
  1469  					"minimum": "2022-06-16T22:19:01.495967Z",
  1470  					"mode":    "2022-06-16T22:19:01.495967Z",
  1471  				},
  1472  			},
  1473  			map[string]interface{}{
  1474  				"timestamp": map[string]interface{}{
  1475  					"count":   json.Number("1"),
  1476  					"maximum": "2022-06-16T22:19:10.339493Z",
  1477  					"median":  "2022-06-16T22:19:10.339493Z",
  1478  					"minimum": "2022-06-16T22:19:10.339493Z",
  1479  					"mode":    "2022-06-16T22:19:10.339493Z",
  1480  				},
  1481  			},
  1482  			map[string]interface{}{
  1483  				"timestamp": map[string]interface{}{
  1484  					"count":   json.Number("1"),
  1485  					"maximum": "2022-06-16T22:19:04.3828349Z",
  1486  					"median":  "2022-06-16T22:19:04.3828349Z",
  1487  					"minimum": "2022-06-16T22:19:04.3828349Z",
  1488  					"mode":    "2022-06-16T22:19:04.3828349Z",
  1489  				},
  1490  			},
  1491  		}
  1492  
  1493  		for _, res := range result {
  1494  			assert.Contains(t, expected, res)
  1495  		}
  1496  	})
  1497  
  1498  	t.Run("group on identical field", func(t *testing.T) {
  1499  		query := `
  1500  		{
  1501  			Aggregate {
  1502  				HasDateField 
  1503  				(
  1504  					groupBy: "identical"
  1505  				)
  1506  				{
  1507  					timestamp {
  1508  						count
  1509  						minimum
  1510  						maximum
  1511  						median
  1512  					}
  1513  				}
  1514  			}
  1515  		}`
  1516  
  1517  		result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, query).Get("Aggregate", "HasDateField").AsSlice()
  1518  
  1519  		expected := []interface{}{
  1520  			map[string]interface{}{
  1521  				"timestamp": map[string]interface{}{
  1522  					"count":   json.Number("10"),
  1523  					"maximum": "2022-06-16T22:19:11.837473Z",
  1524  					"median":  "2022-06-16T22:19:06.1449075Z",
  1525  					"minimum": "2022-06-16T22:18:59.640162Z",
  1526  				},
  1527  			},
  1528  		}
  1529  
  1530  		assert.Equal(t, expected, result)
  1531  	})
  1532  }