Spaces:
Running
Running
// _ _ | |
// __ _____ __ ___ ___ __ _| |_ ___ | |
// \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ | |
// \ V V / __/ (_| |\ V /| | (_| | || __/ | |
// \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| | |
// | |
// Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. | |
// | |
// CONTACT: [email protected] | |
// | |
package test | |
import ( | |
"encoding/json" | |
"fmt" | |
"strconv" | |
"testing" | |
"github.com/stretchr/testify/assert" | |
"github.com/stretchr/testify/require" | |
"github.com/weaviate/weaviate/entities/schema" | |
"github.com/weaviate/weaviate/test/helper" | |
graphqlhelper "github.com/weaviate/weaviate/test/helper/graphql" | |
) | |
// This test prevents a regression on the fix for | |
// https://github.com/weaviate/weaviate/issues/824 | |
func localMeta_StringPropsNotSetEverywhere(t *testing.T) { | |
graphqlhelper.AssertGraphQL(t, helper.RootAuth, ` | |
{ | |
Aggregate { | |
City { | |
name { | |
topOccurrences { | |
occurs | |
value | |
} | |
} | |
} | |
} | |
} | |
`) | |
} | |
func localMetaWithWhereAndNearTextFilters(t *testing.T) { | |
t.Run("with distance", func(t *testing.T) { | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, ` | |
{ | |
Aggregate{ | |
City (where: { | |
valueBoolean: true, | |
operator: Equal, | |
path: ["isCapital"] | |
} | |
nearText: { | |
concepts: ["Amsterdam"] | |
distance: 0.2 | |
} | |
){ | |
meta { | |
count | |
} | |
isCapital { | |
count | |
percentageFalse | |
percentageTrue | |
totalFalse | |
totalTrue | |
type | |
} | |
population { | |
mean | |
count | |
maximum | |
minimum | |
sum | |
type | |
} | |
inCountry { | |
pointingTo | |
type | |
} | |
name { | |
topOccurrences { | |
occurs | |
value | |
} | |
type | |
count | |
} | |
} | |
} | |
} | |
`) | |
t.Run("meta count", func(t *testing.T) { | |
meta := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["meta"] | |
count := meta.(map[string]interface{})["count"] | |
expected := json.Number("1") | |
assert.Equal(t, expected, count) | |
}) | |
t.Run("boolean props", func(t *testing.T) { | |
isCapital := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["isCapital"] | |
expected := map[string]interface{}{ | |
"count": json.Number("1"), | |
"percentageTrue": json.Number("1"), | |
"percentageFalse": json.Number("0"), | |
"totalTrue": json.Number("1"), | |
"totalFalse": json.Number("0"), | |
"type": "boolean", | |
} | |
assert.Equal(t, expected, isCapital) | |
}) | |
t.Run("int/number props", func(t *testing.T) { | |
population := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["population"] | |
expected := map[string]interface{}{ | |
"mean": json.Number("1800000"), | |
"count": json.Number("1"), | |
"maximum": json.Number("1800000"), | |
"minimum": json.Number("1800000"), | |
"sum": json.Number("1800000"), | |
"type": "int", | |
} | |
assert.Equal(t, expected, population) | |
}) | |
t.Run("ref prop", func(t *testing.T) { | |
inCountry := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["inCountry"] | |
expected := map[string]interface{}{ | |
"pointingTo": []interface{}{"Country"}, | |
"type": "cref", | |
} | |
assert.Equal(t, expected, inCountry) | |
}) | |
t.Run("string prop", func(t *testing.T) { | |
name := result.Get("Aggregate", "City"). | |
AsSlice()[0].(map[string]interface{})["name"].(map[string]interface{}) | |
typeField := name["type"] | |
topOccurrences := name["topOccurrences"] | |
assert.Equal(t, schema.DataTypeText.String(), typeField) | |
expectedTopOccurrences := []interface{}{ | |
map[string]interface{}{ | |
"value": "Amsterdam", | |
"occurs": json.Number("1"), | |
}, | |
} | |
assert.ElementsMatch(t, expectedTopOccurrences, topOccurrences) | |
}) | |
}) | |
t.Run("with certainty", func(t *testing.T) { | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, ` | |
{ | |
Aggregate{ | |
City (where: { | |
valueBoolean: true, | |
operator: Equal, | |
path: ["isCapital"] | |
} | |
nearText: { | |
concepts: ["Amsterdam"] | |
certainty: 0.9 | |
} | |
){ | |
meta { | |
count | |
} | |
isCapital { | |
count | |
percentageFalse | |
percentageTrue | |
totalFalse | |
totalTrue | |
type | |
} | |
population { | |
mean | |
count | |
maximum | |
minimum | |
sum | |
type | |
} | |
inCountry { | |
pointingTo | |
type | |
} | |
name { | |
topOccurrences { | |
occurs | |
value | |
} | |
type | |
count | |
} | |
} | |
} | |
}`) | |
t.Run("meta count", func(t *testing.T) { | |
meta := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["meta"] | |
count := meta.(map[string]interface{})["count"] | |
expected := json.Number("1") | |
assert.Equal(t, expected, count) | |
}) | |
t.Run("boolean props", func(t *testing.T) { | |
isCapital := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["isCapital"] | |
expected := map[string]interface{}{ | |
"count": json.Number("1"), | |
"percentageTrue": json.Number("1"), | |
"percentageFalse": json.Number("0"), | |
"totalTrue": json.Number("1"), | |
"totalFalse": json.Number("0"), | |
"type": "boolean", | |
} | |
assert.Equal(t, expected, isCapital) | |
}) | |
t.Run("int/number props", func(t *testing.T) { | |
population := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["population"] | |
expected := map[string]interface{}{ | |
"mean": json.Number("1800000"), | |
"count": json.Number("1"), | |
"maximum": json.Number("1800000"), | |
"minimum": json.Number("1800000"), | |
"sum": json.Number("1800000"), | |
"type": "int", | |
} | |
assert.Equal(t, expected, population) | |
}) | |
t.Run("ref prop", func(t *testing.T) { | |
inCountry := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["inCountry"] | |
expected := map[string]interface{}{ | |
"pointingTo": []interface{}{"Country"}, | |
"type": "cref", | |
} | |
assert.Equal(t, expected, inCountry) | |
}) | |
t.Run("string prop", func(t *testing.T) { | |
name := result.Get("Aggregate", "City"). | |
AsSlice()[0].(map[string]interface{})["name"].(map[string]interface{}) | |
typeField := name["type"] | |
topOccurrences := name["topOccurrences"] | |
assert.Equal(t, schema.DataTypeText.String(), typeField) | |
expectedTopOccurrences := []interface{}{ | |
map[string]interface{}{ | |
"value": "Amsterdam", | |
"occurs": json.Number("1"), | |
}, | |
} | |
assert.ElementsMatch(t, expectedTopOccurrences, topOccurrences) | |
}) | |
}) | |
} | |
func localMetaWithWhereAndNearObjectFilters(t *testing.T) { | |
t.Run("with distance", func(t *testing.T) { | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, ` | |
{ | |
Aggregate{ | |
City (where: { | |
valueBoolean: true, | |
operator: Equal, | |
path: ["isCapital"] | |
} | |
nearObject: { | |
id: "9b9cbea5-e87e-4cd0-89af-e2f424fd52d6" | |
distance: 0.2 | |
} | |
){ | |
meta { | |
count | |
} | |
isCapital { | |
count | |
percentageFalse | |
percentageTrue | |
totalFalse | |
totalTrue | |
type | |
} | |
population { | |
mean | |
count | |
maximum | |
minimum | |
sum | |
type | |
} | |
inCountry { | |
pointingTo | |
type | |
} | |
name { | |
topOccurrences { | |
occurs | |
value | |
} | |
type | |
count | |
} | |
} | |
} | |
}`) | |
t.Run("meta count", func(t *testing.T) { | |
meta := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["meta"] | |
count := meta.(map[string]interface{})["count"] | |
expected := json.Number("1") | |
assert.Equal(t, expected, count) | |
}) | |
t.Run("boolean props", func(t *testing.T) { | |
isCapital := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["isCapital"] | |
expected := map[string]interface{}{ | |
"count": json.Number("1"), | |
"percentageTrue": json.Number("1"), | |
"percentageFalse": json.Number("0"), | |
"totalTrue": json.Number("1"), | |
"totalFalse": json.Number("0"), | |
"type": "boolean", | |
} | |
assert.Equal(t, expected, isCapital) | |
}) | |
t.Run("int/number props", func(t *testing.T) { | |
population := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["population"] | |
expected := map[string]interface{}{ | |
"mean": json.Number("3470000"), | |
"count": json.Number("1"), | |
"maximum": json.Number("3470000"), | |
"minimum": json.Number("3470000"), | |
"sum": json.Number("3470000"), | |
"type": "int", | |
} | |
assert.Equal(t, expected, population) | |
}) | |
t.Run("ref prop", func(t *testing.T) { | |
inCountry := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["inCountry"] | |
expected := map[string]interface{}{ | |
"pointingTo": []interface{}{"Country"}, | |
"type": "cref", | |
} | |
assert.Equal(t, expected, inCountry) | |
}) | |
t.Run("string prop", func(t *testing.T) { | |
name := result.Get("Aggregate", "City"). | |
AsSlice()[0].(map[string]interface{})["name"].(map[string]interface{}) | |
typeField := name["type"] | |
topOccurrences := name["topOccurrences"] | |
assert.Equal(t, schema.DataTypeText.String(), typeField) | |
expectedTopOccurrences := []interface{}{ | |
map[string]interface{}{ | |
"value": "Berlin", | |
"occurs": json.Number("1"), | |
}, | |
} | |
assert.ElementsMatch(t, expectedTopOccurrences, topOccurrences) | |
}) | |
}) | |
t.Run("with certainty", func(t *testing.T) { | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, ` | |
{ | |
Aggregate{ | |
City (where: { | |
valueBoolean: true, | |
operator: Equal, | |
path: ["isCapital"] | |
} | |
nearObject: { | |
id: "9b9cbea5-e87e-4cd0-89af-e2f424fd52d6" | |
certainty: 0.9 | |
} | |
){ | |
meta { | |
count | |
} | |
isCapital { | |
count | |
percentageFalse | |
percentageTrue | |
totalFalse | |
totalTrue | |
type | |
} | |
population { | |
mean | |
count | |
maximum | |
minimum | |
sum | |
type | |
} | |
inCountry { | |
pointingTo | |
type | |
} | |
name { | |
topOccurrences { | |
occurs | |
value | |
} | |
type | |
count | |
} | |
} | |
} | |
}`) | |
t.Run("meta count", func(t *testing.T) { | |
meta := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["meta"] | |
count := meta.(map[string]interface{})["count"] | |
expected := json.Number("1") | |
assert.Equal(t, expected, count) | |
}) | |
t.Run("boolean props", func(t *testing.T) { | |
isCapital := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["isCapital"] | |
expected := map[string]interface{}{ | |
"count": json.Number("1"), | |
"percentageTrue": json.Number("1"), | |
"percentageFalse": json.Number("0"), | |
"totalTrue": json.Number("1"), | |
"totalFalse": json.Number("0"), | |
"type": "boolean", | |
} | |
assert.Equal(t, expected, isCapital) | |
}) | |
t.Run("int/number props", func(t *testing.T) { | |
population := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["population"] | |
expected := map[string]interface{}{ | |
"mean": json.Number("3470000"), | |
"count": json.Number("1"), | |
"maximum": json.Number("3470000"), | |
"minimum": json.Number("3470000"), | |
"sum": json.Number("3470000"), | |
"type": "int", | |
} | |
assert.Equal(t, expected, population) | |
}) | |
t.Run("ref prop", func(t *testing.T) { | |
inCountry := result.Get("Aggregate", "City").AsSlice()[0].(map[string]interface{})["inCountry"] | |
expected := map[string]interface{}{ | |
"pointingTo": []interface{}{"Country"}, | |
"type": "cref", | |
} | |
assert.Equal(t, expected, inCountry) | |
}) | |
t.Run("string prop", func(t *testing.T) { | |
name := result.Get("Aggregate", "City"). | |
AsSlice()[0].(map[string]interface{})["name"].(map[string]interface{}) | |
typeField := name["type"] | |
topOccurrences := name["topOccurrences"] | |
assert.Equal(t, schema.DataTypeText.String(), typeField) | |
expectedTopOccurrences := []interface{}{ | |
map[string]interface{}{ | |
"value": "Berlin", | |
"occurs": json.Number("1"), | |
}, | |
} | |
assert.ElementsMatch(t, expectedTopOccurrences, topOccurrences) | |
}) | |
}) | |
} | |
func localMetaWithNearVectorFilter(t *testing.T) { | |
t.Run("with distance", func(t *testing.T) { | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, ` | |
{ | |
Aggregate{ | |
CustomVectorClass( | |
nearVector: { | |
vector: [1,0,0] | |
distance: 0.0002 | |
} | |
){ | |
meta { | |
count | |
} | |
name { | |
topOccurrences { | |
occurs | |
value | |
} | |
type | |
count | |
} | |
} | |
} | |
}`) | |
t.Run("meta count", func(t *testing.T) { | |
meta := result.Get("Aggregate", "CustomVectorClass").AsSlice()[0].(map[string]interface{})["meta"] | |
count := meta.(map[string]interface{})["count"] | |
expected := json.Number("1") | |
assert.Equal(t, expected, count) | |
}) | |
t.Run("string prop", func(t *testing.T) { | |
name := result.Get("Aggregate", "CustomVectorClass"). | |
AsSlice()[0].(map[string]interface{})["name"].(map[string]interface{}) | |
typeField := name["type"] | |
topOccurrences := name["topOccurrences"] | |
assert.Equal(t, schema.DataTypeText.String(), typeField) | |
expectedTopOccurrences := []interface{}{ | |
map[string]interface{}{ | |
"value": "Mercedes", | |
"occurs": json.Number("1"), | |
}, | |
} | |
assert.ElementsMatch(t, expectedTopOccurrences, topOccurrences) | |
}) | |
}) | |
t.Run("with certainty", func(t *testing.T) { | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, ` | |
{ | |
Aggregate{ | |
CustomVectorClass( | |
nearVector: { | |
vector: [1,0,0] | |
certainty: 0.9999 | |
} | |
){ | |
meta { | |
count | |
} | |
name { | |
topOccurrences { | |
occurs | |
value | |
} | |
type | |
count | |
} | |
} | |
} | |
}`) | |
t.Run("meta count", func(t *testing.T) { | |
meta := result.Get("Aggregate", "CustomVectorClass").AsSlice()[0].(map[string]interface{})["meta"] | |
count := meta.(map[string]interface{})["count"] | |
expected := json.Number("1") | |
assert.Equal(t, expected, count) | |
}) | |
t.Run("string prop", func(t *testing.T) { | |
name := result.Get("Aggregate", "CustomVectorClass"). | |
AsSlice()[0].(map[string]interface{})["name"].(map[string]interface{}) | |
typeField := name["type"] | |
topOccurrences := name["topOccurrences"] | |
assert.Equal(t, schema.DataTypeText.String(), typeField) | |
expectedTopOccurrences := []interface{}{ | |
map[string]interface{}{ | |
"value": "Mercedes", | |
"occurs": json.Number("1"), | |
}, | |
} | |
assert.ElementsMatch(t, expectedTopOccurrences, topOccurrences) | |
}) | |
}) | |
} | |
func localMetaWithWhereAndNearVectorFilters(t *testing.T) { | |
t.Run("with distance", func(t *testing.T) { | |
t.Run("with expected results, low certainty", func(t *testing.T) { | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, ` | |
{ | |
Aggregate { | |
CustomVectorClass( | |
where: { | |
valueText: "Ford" | |
operator: Equal | |
path: ["name"] | |
} | |
nearVector: { | |
vector: [1,0,0] | |
distance: 0.6 | |
} | |
) { | |
meta { | |
count | |
} | |
name { | |
topOccurrences { | |
occurs | |
value | |
} | |
type | |
count | |
} | |
} | |
} | |
} | |
`) | |
require.NotNil(t, result) | |
agg := result.Result.(map[string]interface{})["Aggregate"].(map[string]interface{}) | |
cls := agg["CustomVectorClass"].([]interface{}) | |
require.Len(t, cls, 1) | |
name := cls[0].(map[string]interface{})["name"].(map[string]interface{}) | |
topOcc := name["topOccurrences"].([]interface{}) | |
require.Len(t, topOcc, 1) | |
val := topOcc[0].(map[string]interface{})["value"] | |
assert.Equal(t, "Ford", val) | |
}) | |
t.Run("with no expected results, low distance", func(t *testing.T) { | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, ` | |
{ | |
Aggregate { | |
CustomVectorClass( | |
where: { | |
valueText: "Ford" | |
operator: Equal | |
path: ["name"] | |
} | |
nearVector: { | |
vector: [1,0,0] | |
distance: 0.2 | |
} | |
) { | |
meta { | |
count | |
} | |
name { | |
topOccurrences { | |
occurs | |
value | |
} | |
type | |
count | |
} | |
} | |
} | |
} | |
`) | |
require.NotNil(t, result) | |
agg := result.Result.(map[string]interface{})["Aggregate"].(map[string]interface{}) | |
cls := agg["CustomVectorClass"].([]interface{}) | |
require.Len(t, cls, 1) | |
name := cls[0].(map[string]interface{})["name"].(map[string]interface{}) | |
topOcc := name["topOccurrences"].([]interface{}) | |
require.Len(t, topOcc, 0) | |
}) | |
t.Run("with expected results, low distance", func(t *testing.T) { | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, ` | |
{ | |
Aggregate { | |
CustomVectorClass( | |
where: { | |
valueText: "Mercedes" | |
operator: Equal | |
path: ["name"] | |
} | |
nearVector: { | |
vector: [1,0,0] | |
distance: 0.1 | |
} | |
) { | |
meta { | |
count | |
} | |
name { | |
topOccurrences { | |
occurs | |
value | |
} | |
type | |
count | |
} | |
} | |
} | |
}`) | |
require.NotNil(t, result) | |
agg := result.Result.(map[string]interface{})["Aggregate"].(map[string]interface{}) | |
cls := agg["CustomVectorClass"].([]interface{}) | |
require.Len(t, cls, 1) | |
name := cls[0].(map[string]interface{})["name"].(map[string]interface{}) | |
topOcc := name["topOccurrences"].([]interface{}) | |
require.Len(t, topOcc, 1) | |
val := topOcc[0].(map[string]interface{})["value"] | |
assert.Equal(t, "Mercedes", val) | |
}) | |
}) | |
t.Run("with certainty", func(t *testing.T) { | |
t.Run("with expected results, low certainty", func(t *testing.T) { | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, ` | |
{ | |
Aggregate { | |
CustomVectorClass( | |
where: { | |
valueText: "Ford" | |
operator: Equal | |
path: ["name"] | |
} | |
nearVector: { | |
vector: [1,0,0] | |
certainty: 0.7 | |
} | |
) { | |
meta { | |
count | |
} | |
name { | |
topOccurrences { | |
occurs | |
value | |
} | |
type | |
count | |
} | |
} | |
} | |
} | |
`) | |
require.NotNil(t, result) | |
agg := result.Result.(map[string]interface{})["Aggregate"].(map[string]interface{}) | |
cls := agg["CustomVectorClass"].([]interface{}) | |
require.Len(t, cls, 1) | |
name := cls[0].(map[string]interface{})["name"].(map[string]interface{}) | |
topOcc := name["topOccurrences"].([]interface{}) | |
require.Len(t, topOcc, 1) | |
val := topOcc[0].(map[string]interface{})["value"] | |
assert.Equal(t, "Ford", val) | |
}) | |
t.Run("with no expected results, high certainty", func(t *testing.T) { | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, ` | |
{ | |
Aggregate { | |
CustomVectorClass( | |
where: { | |
valueText: "Ford" | |
operator: Equal | |
path: ["name"] | |
} | |
nearVector: { | |
vector: [1,0,0] | |
certainty: 0.9 | |
} | |
) { | |
meta { | |
count | |
} | |
name { | |
topOccurrences { | |
occurs | |
value | |
} | |
type | |
count | |
} | |
} | |
} | |
} | |
`) | |
require.NotNil(t, result) | |
agg := result.Result.(map[string]interface{})["Aggregate"].(map[string]interface{}) | |
cls := agg["CustomVectorClass"].([]interface{}) | |
require.Len(t, cls, 1) | |
name := cls[0].(map[string]interface{})["name"].(map[string]interface{}) | |
topOcc := name["topOccurrences"].([]interface{}) | |
require.Len(t, topOcc, 0) | |
}) | |
t.Run("with expected results, high certainty", func(t *testing.T) { | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, ` | |
{ | |
Aggregate { | |
CustomVectorClass( | |
where: { | |
valueText: "Mercedes" | |
operator: Equal | |
path: ["name"] | |
} | |
nearVector: { | |
vector: [1,0,0] | |
certainty: 0.9 | |
} | |
) { | |
meta { | |
count | |
} | |
name { | |
topOccurrences { | |
occurs | |
value | |
} | |
type | |
count | |
} | |
} | |
} | |
} | |
`) | |
require.NotNil(t, result) | |
agg := result.Result.(map[string]interface{})["Aggregate"].(map[string]interface{}) | |
cls := agg["CustomVectorClass"].([]interface{}) | |
require.Len(t, cls, 1) | |
name := cls[0].(map[string]interface{})["name"].(map[string]interface{}) | |
topOcc := name["topOccurrences"].([]interface{}) | |
require.Len(t, topOcc, 1) | |
val := topOcc[0].(map[string]interface{})["value"] | |
assert.Equal(t, "Mercedes", val) | |
}) | |
}) | |
} | |
func localMetaWithWhereGroupByNearMediaFilters(t *testing.T) { | |
t.Run("with nearObject", func(t *testing.T) { | |
query := ` | |
{ | |
Aggregate { | |
Company | |
( | |
groupBy: "name" | |
nearObject: {id: "cfa3b21e-ca4f-4db7-a432-7fc6a23c534d", certainty: 0.99} | |
) | |
{ | |
groupedBy { | |
value | |
} | |
meta { | |
count | |
} | |
} | |
} | |
}` | |
expected := map[string]interface{}{ | |
"Aggregate": map[string]interface{}{ | |
"Company": []interface{}{ | |
map[string]interface{}{ | |
"groupedBy": map[string]interface{}{ | |
"value": "Microsoft Inc.", | |
}, | |
"meta": map[string]interface{}{ | |
"count": json.Number("1"), | |
}, | |
}, | |
}, | |
}, | |
} | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, query).Result | |
assert.EqualValues(t, expected, result) | |
}) | |
t.Run("with nearText", func(t *testing.T) { | |
t.Run("with distance", func(t *testing.T) { | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, ` | |
{ | |
Aggregate{ | |
City ( | |
groupBy: "population" | |
where: { | |
valueBoolean: true, | |
operator: Equal, | |
path: ["isCapital"] | |
} | |
nearText: { | |
concepts: ["Amsterdam"] | |
distance: 0.2 | |
} | |
){ | |
meta { | |
count | |
} | |
groupedBy { | |
value | |
} | |
} | |
} | |
} | |
`) | |
expected := map[string]interface{}{ | |
"Aggregate": map[string]interface{}{ | |
"City": []interface{}{ | |
map[string]interface{}{ | |
"groupedBy": map[string]interface{}{ | |
"value": "1.8e+06", | |
}, | |
"meta": map[string]interface{}{ | |
"count": json.Number("1"), | |
}, | |
}, | |
}, | |
}, | |
} | |
assert.EqualValues(t, expected, result.Result) | |
}) | |
t.Run("with certainty", func(t *testing.T) { | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, ` | |
{ | |
Aggregate{ | |
City ( | |
groupBy: "population" | |
where: { | |
valueBoolean: true, | |
operator: Equal, | |
path: ["isCapital"] | |
} | |
nearText: { | |
concepts: ["Amsterdam"] | |
certainty: 0.9 | |
} | |
){ | |
meta { | |
count | |
} | |
groupedBy { | |
value | |
} | |
} | |
} | |
} | |
`) | |
expected := map[string]interface{}{ | |
"Aggregate": map[string]interface{}{ | |
"City": []interface{}{ | |
map[string]interface{}{ | |
"groupedBy": map[string]interface{}{ | |
"value": "1.8e+06", | |
}, | |
"meta": map[string]interface{}{ | |
"count": json.Number("1"), | |
}, | |
}, | |
}, | |
}, | |
} | |
assert.EqualValues(t, expected, result.Result) | |
}) | |
}) | |
t.Run("with nearVector", func(t *testing.T) { | |
getQuery := ` | |
{ | |
Get { | |
Company(where: { | |
path: ["name"] | |
operator: Equal | |
valueText: "Google Inc." | |
}) | |
{ | |
_additional { | |
vector | |
} | |
} | |
} | |
}` | |
vectorResult := graphqlhelper.AssertGraphQL(t, helper.RootAuth, getQuery). | |
Get("Get", "Company"). | |
AsSlice()[0].(map[string]interface{})["_additional"].(map[string]interface{})["vector"].([]interface{}) | |
vector := make([]float32, len(vectorResult)) | |
for i, ifc := range vectorResult { | |
val, err := strconv.ParseFloat(ifc.(json.Number).String(), 32) | |
require.Nil(t, err) | |
vector[i] = float32(val) | |
} | |
aggQuery := fmt.Sprintf(` | |
{ | |
Aggregate { | |
Company | |
( | |
groupBy: "name" | |
nearVector: {vector: %+v, certainty: 0.99} | |
) | |
{ | |
groupedBy { | |
value | |
} | |
meta { | |
count | |
} | |
} | |
} | |
} | |
`, vector) | |
aggResult := graphqlhelper.AssertGraphQL(t, helper.RootAuth, aggQuery).Result | |
expected := map[string]interface{}{ | |
"Aggregate": map[string]interface{}{ | |
"Company": []interface{}{ | |
map[string]interface{}{ | |
"groupedBy": map[string]interface{}{ | |
"value": "Google Inc.", | |
}, | |
"meta": map[string]interface{}{ | |
"count": json.Number("1"), | |
}, | |
}, | |
}, | |
}, | |
} | |
assert.EqualValues(t, expected, aggResult) | |
}) | |
} | |
func localMetaWithObjectLimit(t *testing.T) { | |
t.Run("with nearObject and distance", func(t *testing.T) { | |
objectLimit := 1 | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, fmt.Sprintf(` | |
{ | |
Aggregate{ | |
City ( | |
objectLimit: %d | |
nearObject: { | |
id: "9b9cbea5-e87e-4cd0-89af-e2f424fd52d6" | |
distance: 0.3 | |
} | |
){ | |
meta { | |
count | |
} | |
} | |
} | |
} | |
`, objectLimit)) | |
t.Run("validate objectLimit functions as expected", func(t *testing.T) { | |
res := result.Get("Aggregate", "City").AsSlice() | |
require.Len(t, res, 1) | |
meta := res[0].(map[string]interface{})["meta"] | |
count := meta.(map[string]interface{})["count"] | |
assert.Equal(t, json.Number(fmt.Sprint(objectLimit)), count) | |
}) | |
}) | |
t.Run("with nearObject and certainty", func(t *testing.T) { | |
objectLimit := 1 | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, fmt.Sprintf(` | |
{ | |
Aggregate{ | |
City ( | |
objectLimit: %d | |
nearObject: { | |
id: "9b9cbea5-e87e-4cd0-89af-e2f424fd52d6" | |
certainty: 0.7 | |
} | |
){ | |
meta { | |
count | |
} | |
} | |
} | |
} | |
`, objectLimit)) | |
t.Run("validate objectLimit functions as expected", func(t *testing.T) { | |
res := result.Get("Aggregate", "City").AsSlice() | |
require.Len(t, res, 1) | |
meta := res[0].(map[string]interface{})["meta"] | |
count := meta.(map[string]interface{})["count"] | |
assert.Equal(t, json.Number(fmt.Sprint(objectLimit)), count) | |
}) | |
}) | |
t.Run("with nearObject and no certainty", func(t *testing.T) { | |
objectLimit := 2 | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, fmt.Sprintf(` | |
{ | |
Aggregate{ | |
City ( | |
objectLimit: %d | |
nearObject: { | |
id: "9b9cbea5-e87e-4cd0-89af-e2f424fd52d6" | |
} | |
){ | |
meta { | |
count | |
} | |
} | |
} | |
} | |
`, objectLimit)) | |
t.Run("validate objectLimit functions as expected", func(t *testing.T) { | |
res := result.Get("Aggregate", "City").AsSlice() | |
require.Len(t, res, 1) | |
meta := res[0].(map[string]interface{})["meta"] | |
count := meta.(map[string]interface{})["count"] | |
assert.Equal(t, json.Number(fmt.Sprint(objectLimit)), count) | |
}) | |
}) | |
t.Run("with nearObject and very high distance, no objectLimit", func(t *testing.T) { | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, ` | |
{ | |
Aggregate { | |
RansomNote( | |
nearText: { | |
concepts: ["abc"] | |
distance: 1.9998 | |
} | |
) { | |
meta { | |
count | |
} | |
} | |
} | |
} | |
`) | |
t.Run("validate nearMedia runs unlimited without objectLimit", func(t *testing.T) { | |
res := result.Get("Aggregate", "RansomNote").AsSlice() | |
require.Len(t, res, 1) | |
meta := res[0].(map[string]interface{})["meta"] | |
count := meta.(map[string]interface{})["count"] | |
assert.Equal(t, json.Number("500"), count) | |
}) | |
}) | |
t.Run("with nearObject and very low certainty, no objectLimit", func(t *testing.T) { | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, ` | |
{ | |
Aggregate { | |
RansomNote( | |
nearText: { | |
concepts: ["abc"] | |
certainty: 0.0001 | |
} | |
) { | |
meta { | |
count | |
} | |
} | |
} | |
} | |
`) | |
t.Run("validate nearMedia runs unlimited without objectLimit", func(t *testing.T) { | |
res := result.Get("Aggregate", "RansomNote").AsSlice() | |
require.Len(t, res, 1) | |
meta := res[0].(map[string]interface{})["meta"] | |
count := meta.(map[string]interface{})["count"] | |
assert.Equal(t, json.Number("500"), count) | |
}) | |
}) | |
t.Run("with nearObject and low distance (few results), high objectLimit", func(t *testing.T) { | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, ` | |
{ | |
Aggregate { | |
RansomNote( | |
nearText: { | |
concepts: ["abc"] | |
distance: 0.6 # should return about 6 elements | |
} | |
objectLimit:100, | |
) { | |
meta { | |
count | |
} | |
} | |
} | |
} | |
`) | |
t.Run("validate fewer than objectLimit elements are returned", func(t *testing.T) { | |
res := result.Get("Aggregate", "RansomNote").AsSlice() | |
require.Len(t, res, 1) | |
meta := res[0].(map[string]interface{})["meta"] | |
count := meta.(map[string]interface{})["count"] | |
countParsed, err := count.(json.Number).Int64() | |
require.Nil(t, err) | |
assert.Less(t, countParsed, int64(100)) | |
}) | |
}) | |
t.Run("with nearObject and high certainty (few results), high objectLimit", func(t *testing.T) { | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, ` | |
{ | |
Aggregate { | |
RansomNote( | |
nearText: { | |
concepts: ["abc"] | |
certainty: 0.7 # should return about 6 elements | |
} | |
objectLimit:100, | |
) { | |
meta { | |
count | |
} | |
} | |
} | |
} | |
`) | |
t.Run("validate fewer than objectLimit elements are returned", func(t *testing.T) { | |
res := result.Get("Aggregate", "RansomNote").AsSlice() | |
require.Len(t, res, 1) | |
meta := res[0].(map[string]interface{})["meta"] | |
count := meta.(map[string]interface{})["count"] | |
countParsed, err := count.(json.Number).Int64() | |
require.Nil(t, err) | |
assert.Less(t, countParsed, int64(100)) | |
}) | |
}) | |
t.Run("with nearText and no distance/certainty, where filter and groupBy", func(t *testing.T) { | |
objectLimit := 4 | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, fmt.Sprintf(` | |
{ | |
Aggregate { | |
Company ( | |
groupBy: ["name"] | |
where: { | |
valueText: "Apple*", | |
operator: Like, | |
path: ["name"] | |
} | |
objectLimit: %d | |
nearText: { | |
concepts: ["Apple"] | |
certainty: 0.5 | |
} | |
){ | |
meta { | |
count | |
} | |
groupedBy { | |
value | |
} | |
} | |
} | |
} | |
`, objectLimit)) | |
expected := []interface{}{ | |
map[string]interface{}{ | |
"groupedBy": map[string]interface{}{ | |
"value": "Apple Incorporated", | |
}, | |
"meta": map[string]interface{}{ | |
"count": json.Number("1"), | |
}, | |
}, | |
map[string]interface{}{ | |
"groupedBy": map[string]interface{}{ | |
"value": "Apple Inc.", | |
}, | |
"meta": map[string]interface{}{ | |
"count": json.Number("1"), | |
}, | |
}, | |
map[string]interface{}{ | |
"groupedBy": map[string]interface{}{ | |
"value": "Apple", | |
}, | |
"meta": map[string]interface{}{ | |
"count": json.Number("1"), | |
}, | |
}, | |
} | |
companies := result.Get("Aggregate", "Company").Result.([]interface{}) | |
for _, company := range companies { | |
assert.Contains(t, expected, company) | |
} | |
}) | |
t.Run("with nearObject and certainty, where filter", func(t *testing.T) { | |
objectLimit := 1 | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, fmt.Sprintf(` | |
{ | |
Aggregate{ | |
City ( | |
where: { | |
valueBoolean: true, | |
operator: Equal, | |
path: ["isCapital"] | |
} | |
objectLimit: %d | |
nearObject: { | |
id: "9b9cbea5-e87e-4cd0-89af-e2f424fd52d6" | |
} | |
){ | |
meta { | |
count | |
} | |
} | |
} | |
} | |
`, objectLimit)) | |
t.Run("validate objectLimit functions as expected", func(t *testing.T) { | |
res := result.Get("Aggregate", "City").AsSlice() | |
require.Len(t, res, 1) | |
meta := res[0].(map[string]interface{})["meta"] | |
count := meta.(map[string]interface{})["count"] | |
assert.Equal(t, json.Number(fmt.Sprint(objectLimit)), count) | |
}) | |
}) | |
} | |
func aggregatesOnDateFields(t *testing.T) { | |
t.Run("without grouping", func(t *testing.T) { | |
query := ` | |
{ | |
Aggregate { | |
HasDateField { | |
timestamp { | |
count | |
minimum | |
maximum | |
median | |
} | |
} | |
} | |
}` | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, query).Get("Aggregate", "HasDateField").AsSlice() | |
assert.Len(t, result, 1) | |
expected := []interface{}{ | |
map[string]interface{}{ | |
"timestamp": map[string]interface{}{ | |
"count": json.Number("10"), | |
"maximum": "2022-06-16T22:19:11.837473Z", | |
"median": "2022-06-16T22:19:06.1449075Z", | |
"minimum": "2022-06-16T22:18:59.640162Z", | |
}, | |
}, | |
} | |
assert.Equal(t, expected, result) | |
}) | |
t.Run("with grouping on a unique field", func(t *testing.T) { | |
query := ` | |
{ | |
Aggregate { | |
HasDateField | |
( | |
groupBy: "unique" | |
) | |
{ | |
timestamp { | |
count | |
minimum | |
maximum | |
median | |
mode | |
} | |
} | |
} | |
}` | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, query).Get("Aggregate", "HasDateField").AsSlice() | |
assert.Len(t, result, 10) | |
expected := []interface{}{ | |
map[string]interface{}{ | |
"timestamp": map[string]interface{}{ | |
"count": json.Number("1"), | |
"maximum": "2022-06-16T22:19:05.894857Z", | |
"median": "2022-06-16T22:19:05.894857Z", | |
"minimum": "2022-06-16T22:19:05.894857Z", | |
"mode": "2022-06-16T22:19:05.894857Z", | |
}, | |
}, | |
map[string]interface{}{ | |
"timestamp": map[string]interface{}{ | |
"count": json.Number("1"), | |
"maximum": "2022-06-16T22:19:08.112395Z", | |
"median": "2022-06-16T22:19:08.112395Z", | |
"minimum": "2022-06-16T22:19:08.112395Z", | |
"mode": "2022-06-16T22:19:08.112395Z", | |
}, | |
}, | |
map[string]interface{}{ | |
"timestamp": map[string]interface{}{ | |
"count": json.Number("1"), | |
"maximum": "2022-06-16T22:19:03.495596Z", | |
"median": "2022-06-16T22:19:03.495596Z", | |
"minimum": "2022-06-16T22:19:03.495596Z", | |
"mode": "2022-06-16T22:19:03.495596Z", | |
}, | |
}, | |
map[string]interface{}{ | |
"timestamp": map[string]interface{}{ | |
"count": json.Number("1"), | |
"maximum": "2022-06-16T22:19:07.589828Z", | |
"median": "2022-06-16T22:19:07.589828Z", | |
"minimum": "2022-06-16T22:19:07.589828Z", | |
"mode": "2022-06-16T22:19:07.589828Z", | |
}, | |
}, | |
map[string]interface{}{ | |
"timestamp": map[string]interface{}{ | |
"count": json.Number("1"), | |
"maximum": "2022-06-16T22:19:06.394958Z", | |
"median": "2022-06-16T22:19:06.394958Z", | |
"minimum": "2022-06-16T22:19:06.394958Z", | |
"mode": "2022-06-16T22:19:06.394958Z", | |
}, | |
}, | |
map[string]interface{}{ | |
"timestamp": map[string]interface{}{ | |
"count": json.Number("1"), | |
"maximum": "2022-06-16T22:19:11.837473Z", | |
"median": "2022-06-16T22:19:11.837473Z", | |
"minimum": "2022-06-16T22:19:11.837473Z", | |
"mode": "2022-06-16T22:19:11.837473Z", | |
}, | |
}, | |
map[string]interface{}{ | |
"timestamp": map[string]interface{}{ | |
"count": json.Number("1"), | |
"maximum": "2022-06-16T22:18:59.640162Z", | |
"median": "2022-06-16T22:18:59.640162Z", | |
"minimum": "2022-06-16T22:18:59.640162Z", | |
"mode": "2022-06-16T22:18:59.640162Z", | |
}, | |
}, | |
map[string]interface{}{ | |
"timestamp": map[string]interface{}{ | |
"count": json.Number("1"), | |
"maximum": "2022-06-16T22:19:01.495967Z", | |
"median": "2022-06-16T22:19:01.495967Z", | |
"minimum": "2022-06-16T22:19:01.495967Z", | |
"mode": "2022-06-16T22:19:01.495967Z", | |
}, | |
}, | |
map[string]interface{}{ | |
"timestamp": map[string]interface{}{ | |
"count": json.Number("1"), | |
"maximum": "2022-06-16T22:19:10.339493Z", | |
"median": "2022-06-16T22:19:10.339493Z", | |
"minimum": "2022-06-16T22:19:10.339493Z", | |
"mode": "2022-06-16T22:19:10.339493Z", | |
}, | |
}, | |
map[string]interface{}{ | |
"timestamp": map[string]interface{}{ | |
"count": json.Number("1"), | |
"maximum": "2022-06-16T22:19:04.3828349Z", | |
"median": "2022-06-16T22:19:04.3828349Z", | |
"minimum": "2022-06-16T22:19:04.3828349Z", | |
"mode": "2022-06-16T22:19:04.3828349Z", | |
}, | |
}, | |
} | |
for _, res := range result { | |
assert.Contains(t, expected, res) | |
} | |
}) | |
t.Run("group on identical field", func(t *testing.T) { | |
query := ` | |
{ | |
Aggregate { | |
HasDateField | |
( | |
groupBy: "identical" | |
) | |
{ | |
timestamp { | |
count | |
minimum | |
maximum | |
median | |
} | |
} | |
} | |
}` | |
result := graphqlhelper.AssertGraphQL(t, helper.RootAuth, query).Get("Aggregate", "HasDateField").AsSlice() | |
expected := []interface{}{ | |
map[string]interface{}{ | |
"timestamp": map[string]interface{}{ | |
"count": json.Number("10"), | |
"maximum": "2022-06-16T22:19:11.837473Z", | |
"median": "2022-06-16T22:19:06.1449075Z", | |
"minimum": "2022-06-16T22:18:59.640162Z", | |
}, | |
}, | |
} | |
assert.Equal(t, expected, result) | |
}) | |
} | |