diff --git a/connector/fields.go b/connector/fields.go index 94090b0..c6ea244 100644 --- a/connector/fields.go +++ b/connector/fields.go @@ -49,7 +49,7 @@ func handleFieldTypeAggregateMetricDouble(fieldMap map[string]interface{}) { // This compound scalar type supports a superset of comparison and aggregation operations of all its subtypes and the actualType // This compund scalar type is added to the scalarTypeMap before being returned func GetFieldType(fieldMap map[string]interface{}, state *types.State, indexName string, fieldName string) string { - fieldTypes := internal.ExtractTypes(fieldMap) + fieldTypes, _, _ := internal.ExtractTypes(fieldMap) actualFieldType := fieldTypes[0] // actualFieldType is the type type of the field that the db has. It is the main type, not the subtype if len(fieldTypes) > 1 { diff --git a/connector/fields_test.go b/connector/fields_test.go index 881135e..e3d7830 100644 --- a/connector/fields_test.go +++ b/connector/fields_test.go @@ -26,6 +26,9 @@ var tests = []test{ { name: "books", }, + { + name: "books_2", + }, } func TestSchema(t *testing.T) { diff --git a/connector/query_test.go b/connector/query_test.go index 13c6181..7eb4970 100644 --- a/connector/query_test.go +++ b/connector/query_test.go @@ -85,11 +85,15 @@ var tests = []test{ group: "payments", name: "simple_terms_clause", }, + { + group: "customers", + name: "sort_by_subtype", + }, } func TestPrepareElasticsearchQuery(t *testing.T) { for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { + t.Run(tt.group + "." + tt.name, func(t *testing.T) { ctx := context.Background() ctx = context.WithValue(ctx, "postProcessor", &types.PostProcessor{}) initTest(t, &tt) diff --git a/connector/sort.go b/connector/sort.go index 46a1855..9973e7e 100644 --- a/connector/sort.go +++ b/connector/sort.go @@ -39,18 +39,16 @@ func prepareSortElement(element *schema.OrderByElement, state *types.State, coll }) } - fieldType, fieldSubTypes, fieldDataEnabled, err := state.Configuration.GetFieldProperties(collection, fieldPath) + fieldType, subFieldMap, fieldDataEnabled, err := state.Configuration.GetFieldProperties(collection, fieldPath) if err != nil { return nil, schema.InternalServerError("failed to get field types", map[string]any{"error": err.Error()}) } if !internal.IsSortSupported(fieldType, fieldDataEnabled) { - // we iterate over the fieldSubTypes in reverse because the subtypes are sorted by priority. - // We want to use the highest priority subType that is supported for sorting. - for i := len(fieldSubTypes) - 1; i >= 0; i-- { - subType := fieldSubTypes[i] - if internal.IsSortSupported(subType, fieldDataEnabled) { - validField = fmt.Sprintf("%s.%s", validField, subType) + // since the type does not support sorting, we iterate over the subfields to find a subfield that does + for subFieldType, subField := range subFieldMap { + if internal.IsSortSupported(subFieldType, fieldDataEnabled) { + validField = fmt.Sprintf("%s.%s", validField, subField) break } } diff --git a/internal/fields.go b/internal/fields.go index 89bd212..52e06a4 100644 --- a/internal/fields.go +++ b/internal/fields.go @@ -1,18 +1,38 @@ package internal // Given a fieldMap, this function extracts the type and all subtypes (if present) -func ExtractTypes(fieldMap map[string]interface{}) (fieldAndSubfields []string) { +// +// **RETURNS** +// 1. legacyFieldAndSubfields: a slice of strings containing the field type as the first element and all subfields in the following elements. Called legacy because it supports older code that expects this format. Please refrain from using this in newer functions. +// 2. fieldType: the type of the field +// 3. subFieldsMap: a map of types to their subfields +func ExtractTypes(fieldMap map[string]interface{}) (legacyFieldAndSubfields []string, fieldType string, subFieldsMap map[string]string) { + subFieldsMap = make(map[string]string) // subFieldsMap is a map of types and their subFields + fieldType, _ = FieldTypeIsScalar(fieldMap) + if subFields, ok := HasSubfields(fieldMap); ok { - for _, subFieldData := range subFields { - fieldAndSubfields = append(fieldAndSubfields, ExtractTypes(subFieldData.(map[string]interface{}))...) + for subField, subFieldData := range subFields { + subFieldType, ok := subFieldData.(map[string]interface{})["type"].(string) + if !ok { + continue + } + if subFieldType == fieldType { + // since the subfield type is the same as the field type, we will consider the main field type + continue + } + if _, ok := subFieldsMap[subFieldType]; ok { + // subFieldType already exists, skip + continue + } + legacyFieldAndSubfields = append(legacyFieldAndSubfields, subFieldType) + subFieldsMap[subFieldType] = subField } } - SortTypesByPriority(fieldAndSubfields) + SortTypesByPriority(legacyFieldAndSubfields) - fieldType, _ := FieldTypeIsScalar(fieldMap) - fieldAndSubfields = append([]string{fieldType}, fieldAndSubfields...) - return fieldAndSubfields + legacyFieldAndSubfields = append([]string{fieldType}, legacyFieldAndSubfields...) + return legacyFieldAndSubfields, fieldType, subFieldsMap } func HasSubfields(fieldMap map[string]interface{}) (subFields map[string]interface{}, ok bool) { @@ -24,7 +44,7 @@ func HasSubfields(fieldMap map[string]interface{}) (subFields map[string]interfa * This function checks if a field is a scalar field * Scalar field here refers to a field that does not have any nested fields/properties */ - func FieldTypeIsScalar(fieldMap map[string]interface{}) (fieldType string, isFieldScalar bool) { +func FieldTypeIsScalar(fieldMap map[string]interface{}) (fieldType string, isFieldScalar bool) { fieldType, ok := fieldMap["type"].(string) return fieldType, ok && fieldType != "nested" && fieldType != "object" && fieldType != "flattened" } @@ -65,4 +85,4 @@ func IsFieldDtaEnabled(fieldMap map[string]interface{}) bool { fieldDataEnalbed = fieldData } return fieldDataEnalbed -} \ No newline at end of file +} diff --git a/internal/fields_test.go b/internal/fields_test.go new file mode 100644 index 0000000..fcf6f16 --- /dev/null +++ b/internal/fields_test.go @@ -0,0 +1,132 @@ +package internal + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" +) + +var fieldsAndSubfieldsTests = []struct { + name string + fieldMapStr string + wantLegacyFieldAndSubfields []string + wantType string + wantSubFieldsMap map[string]string +}{ + { + name: "nested_field", + fieldMapStr: `{ + "type": "text", + "fields": { + "raw": { + "type": "keyword" + } + } + }`, + wantLegacyFieldAndSubfields: []string{"text", "keyword"}, + wantType: "text", + wantSubFieldsMap: map[string]string{"keyword": "raw"}, + }, + { + name: "nested_fields", + fieldMapStr: `{ + "type": "text", + "fields": { + "raw": { + "type": "keyword" + }, + "raw_int": { + "type": "integer" + }, + "raw_double": { + "type": "double" + }, + "simple_boolean": { + "type": "boolean" + }, + "ip": { + "type": "ip" + }, + "version": { + "type": "version" + } + } + }`, + wantLegacyFieldAndSubfields: []string{ + "text", + "boolean", + "integer", + "double", + "ip", + "keyword", + "version", + }, + wantType: "text", + wantSubFieldsMap: map[string]string{ + "keyword": "raw", + "integer": "raw_int", + "double": "raw_double", + "boolean": "simple_boolean", + "ip": "ip", + "version": "version", + }, + }, + { + name: "no_nested_field", + fieldMapStr: `{ + "type": "keyword" + }`, + wantLegacyFieldAndSubfields: []string{"keyword"}, + wantType: "keyword", + wantSubFieldsMap: map[string]string{}, + }, + { + name: "nested_field_type_same_as_field_type", + fieldMapStr: `{ + "type": "text", + "fields": { + "english": { + "type": "text", + "analyzer": "english" + } + } + }`, + wantLegacyFieldAndSubfields: []string{"text"}, + wantType: "text", + wantSubFieldsMap: map[string]string{}, + }, + { + name: "duplicate_nested_field", + fieldMapStr: `{ + "type": "text", + "fields": { + "raw": { + "type": "keyword" + }, + "raw": { + "type": "keyword" + } + } + }`, + wantLegacyFieldAndSubfields: []string{"text", "keyword"}, + wantType: "text", + wantSubFieldsMap: map[string]string{"keyword": "raw"}, + }, +} + +func TestExtractTypes(t *testing.T) { + for _, tt := range fieldsAndSubfieldsTests { + t.Run(tt.name, func(t *testing.T) { + var fieldMap map[string]interface{} + err := json.Unmarshal([]byte(tt.fieldMapStr), &fieldMap) + assert.NoError(t, err, "Error unmarshalling JSON") + + fieldAndSubfields, fieldType, subFieldsMap := ExtractTypes(fieldMap) + + assert.Equal(t, tt.wantLegacyFieldAndSubfields, fieldAndSubfields) + assert.Equal(t, tt.wantType, fieldType) + assert.Equal(t, tt.wantSubFieldsMap, subFieldsMap) + }) + } +} diff --git a/testdata/unit_tests/fields_tests/books_2/configuration.json b/testdata/unit_tests/fields_tests/books_2/configuration.json new file mode 100644 index 0000000..5237c06 --- /dev/null +++ b/testdata/unit_tests/fields_tests/books_2/configuration.json @@ -0,0 +1,38 @@ +{ + "indices": { + "my_book_index": { + "mappings": { + "properties": { + "author": { + "type": "keyword" + }, + "description": { + "type": "text" + }, + "genre": { + "type": "keyword" + }, + "pages": { + "type": "integer" + }, + "published_date": { + "format": "yyyy-MM-dd", + "type": "date" + }, + "rating": { + "type": "float" + }, + "title": { + "fields": { + "keywordSubField": { + "type": "keyword" + } + }, + "type": "text" + } + } + } + } + }, + "queries": {} +} \ No newline at end of file diff --git a/testdata/unit_tests/fields_tests/books_2/want_schema.json b/testdata/unit_tests/fields_tests/books_2/want_schema.json new file mode 100644 index 0000000..3b6440c --- /dev/null +++ b/testdata/unit_tests/fields_tests/books_2/want_schema.json @@ -0,0 +1,944 @@ +{ + "collections": [ + { + "arguments": {}, + "foreign_keys": {}, + "name": "my_book_index", + "type": "my_book_index", + "uniqueness_constraints": {} + } + ], + "functions": [], + "object_types": { + "date_range_query": { + "fields": { + "boost": { + "description": "(Optional, float) Floating point number used to decrease or increase the relevance scores of a query. Defaults to 1.0.", + "type": { + "name": "float", + "type": "named" + } + }, + "format": { + "description": "(Optional, string) Date format used to convert date values in the query.", + "type": { + "name": "keyword", + "type": "named" + } + }, + "gt": { + "description": "(Optional) Greater than.", + "type": { + "name": "double", + "type": "named" + } + }, + "gte": { + "description": "(Optional) Greater than or equal.", + "type": { + "name": "double", + "type": "named" + } + }, + "lt": { + "description": "(Optional) Less than.", + "type": { + "name": "double", + "type": "named" + } + }, + "lte": { + "description": "(Optional) Less than or equal.", + "type": { + "name": "double", + "type": "named" + } + }, + "time_zone": { + "description": "(Optional, string) Coordinated Universal Time (UTC) offset or IANA time zone used to convert date values in the query to UTC.", + "type": { + "name": "keyword", + "type": "named" + } + } + } + }, + "my_book_index": { + "fields": { + "_id": { + "type": { + "name": "_id", + "type": "named" + } + }, + "author": { + "type": { + "name": "keyword", + "type": "named" + } + }, + "description": { + "type": { + "name": "text", + "type": "named" + } + }, + "genre": { + "type": { + "name": "keyword", + "type": "named" + } + }, + "pages": { + "type": { + "name": "integer", + "type": "named" + } + }, + "published_date": { + "type": { + "name": "date", + "type": "named" + } + }, + "rating": { + "type": { + "name": "float", + "type": "named" + } + }, + "title": { + "type": { + "name": "text.keyword", + "type": "named" + } + } + } + }, + "range": { + "fields": { + "boost": { + "description": "(Optional, float) Floating point number used to decrease or increase the relevance scores of a query. Defaults to 1.0.", + "type": { + "name": "float", + "type": "named" + } + }, + "gt": { + "description": "(Optional) Greater than.", + "type": { + "name": "double", + "type": "named" + } + }, + "gte": { + "description": "(Optional) Greater than or equal.", + "type": { + "name": "double", + "type": "named" + } + }, + "lt": { + "description": "(Optional) Less than.", + "type": { + "name": "double", + "type": "named" + } + }, + "lte": { + "description": "(Optional) Less than or equal.", + "type": { + "name": "double", + "type": "named" + } + } + } + }, + "stats": { + "fields": { + "avg": { + "type": { + "name": "double", + "type": "named" + } + }, + "count": { + "type": { + "name": "integer", + "type": "named" + } + }, + "max": { + "type": { + "name": "double", + "type": "named" + } + }, + "min": { + "type": { + "name": "double", + "type": "named" + } + }, + "sum": { + "type": { + "name": "double", + "type": "named" + } + } + } + }, + "string_stats": { + "fields": { + "avg_length": { + "type": { + "name": "double", + "type": "named" + } + }, + "count": { + "type": { + "name": "integer", + "type": "named" + } + }, + "entropy": { + "type": { + "name": "double", + "type": "named" + } + }, + "max_length": { + "type": { + "name": "integer", + "type": "named" + } + }, + "min_length": { + "type": { + "name": "integer", + "type": "named" + } + } + } + } + }, + "procedures": [], + "scalar_types": { + "_id": { + "aggregate_functions": {}, + "comparison_operators": { + "match": { + "argument_type": { + "name": "_id", + "type": "named" + }, + "type": "custom" + }, + "match_phrase": { + "argument_type": { + "name": "_id", + "type": "named" + }, + "type": "custom" + }, + "term": { + "type": "equal" + }, + "terms": { + "argument_type": { + "element_type": { + "name": "_id", + "type": "named" + }, + "type": "array" + }, + "type": "custom" + } + }, + "representation": { + "type": "string" + } + }, + "date": { + "aggregate_functions": { + "avg": { + "result_type": { + "name": "long", + "type": "named" + } + }, + "cardinality": { + "result_type": { + "name": "integer", + "type": "named" + } + }, + "max": { + "result_type": { + "name": "long", + "type": "named" + } + }, + "min": { + "result_type": { + "name": "long", + "type": "named" + } + }, + "stats": { + "result_type": { + "name": "stats", + "type": "named" + } + }, + "sum": { + "result_type": { + "name": "long", + "type": "named" + } + }, + "value_count": { + "result_type": { + "name": "integer", + "type": "named" + } + } + }, + "comparison_operators": { + "match": { + "argument_type": { + "name": "date", + "type": "named" + }, + "type": "custom" + }, + "match_phrase": { + "argument_type": { + "name": "date", + "type": "named" + }, + "type": "custom" + }, + "range": { + "argument_type": { + "name": "date_range_query", + "type": "named" + }, + "type": "custom" + }, + "term": { + "type": "equal" + }, + "terms": { + "argument_type": { + "element_type": { + "name": "date", + "type": "named" + }, + "type": "array" + }, + "type": "custom" + } + }, + "representation": { + "type": "string" + } + }, + "double": { + "aggregate_functions": { + "avg": { + "result_type": { + "name": "double", + "type": "named" + } + }, + "cardinality": { + "result_type": { + "name": "integer", + "type": "named" + } + }, + "max": { + "result_type": { + "name": "double", + "type": "named" + } + }, + "min": { + "result_type": { + "name": "double", + "type": "named" + } + }, + "stats": { + "result_type": { + "name": "stats", + "type": "named" + } + }, + "sum": { + "result_type": { + "name": "double", + "type": "named" + } + }, + "value_count": { + "result_type": { + "name": "integer", + "type": "named" + } + } + }, + "comparison_operators": { + "match": { + "argument_type": { + "name": "double", + "type": "named" + }, + "type": "custom" + }, + "match_phrase": { + "argument_type": { + "name": "double", + "type": "named" + }, + "type": "custom" + }, + "range": { + "argument_type": { + "name": "range", + "type": "named" + }, + "type": "custom" + }, + "term": { + "type": "equal" + }, + "terms": { + "argument_type": { + "element_type": { + "name": "double", + "type": "named" + }, + "type": "array" + }, + "type": "custom" + } + }, + "representation": { + "type": "number" + } + }, + "float": { + "aggregate_functions": { + "avg": { + "result_type": { + "name": "float", + "type": "named" + } + }, + "cardinality": { + "result_type": { + "name": "integer", + "type": "named" + } + }, + "max": { + "result_type": { + "name": "float", + "type": "named" + } + }, + "min": { + "result_type": { + "name": "float", + "type": "named" + } + }, + "stats": { + "result_type": { + "name": "stats", + "type": "named" + } + }, + "sum": { + "result_type": { + "name": "float", + "type": "named" + } + }, + "value_count": { + "result_type": { + "name": "integer", + "type": "named" + } + } + }, + "comparison_operators": { + "match": { + "argument_type": { + "name": "float", + "type": "named" + }, + "type": "custom" + }, + "match_phrase": { + "argument_type": { + "name": "float", + "type": "named" + }, + "type": "custom" + }, + "range": { + "argument_type": { + "name": "range", + "type": "named" + }, + "type": "custom" + }, + "term": { + "type": "equal" + }, + "terms": { + "argument_type": { + "element_type": { + "name": "float", + "type": "named" + }, + "type": "array" + }, + "type": "custom" + } + }, + "representation": { + "type": "number" + } + }, + "integer": { + "aggregate_functions": { + "avg": { + "result_type": { + "name": "integer", + "type": "named" + } + }, + "cardinality": { + "result_type": { + "name": "integer", + "type": "named" + } + }, + "max": { + "result_type": { + "name": "integer", + "type": "named" + } + }, + "min": { + "result_type": { + "name": "integer", + "type": "named" + } + }, + "stats": { + "result_type": { + "name": "stats", + "type": "named" + } + }, + "sum": { + "result_type": { + "name": "integer", + "type": "named" + } + }, + "value_count": { + "result_type": { + "name": "integer", + "type": "named" + } + } + }, + "comparison_operators": { + "match": { + "argument_type": { + "name": "integer", + "type": "named" + }, + "type": "custom" + }, + "match_phrase": { + "argument_type": { + "name": "integer", + "type": "named" + }, + "type": "custom" + }, + "range": { + "argument_type": { + "name": "range", + "type": "named" + }, + "type": "custom" + }, + "term": { + "type": "equal" + }, + "terms": { + "argument_type": { + "element_type": { + "name": "integer", + "type": "named" + }, + "type": "array" + }, + "type": "custom" + } + }, + "representation": { + "type": "integer" + } + }, + "keyword": { + "aggregate_functions": { + "cardinality": { + "result_type": { + "name": "integer", + "type": "named" + } + }, + "string_stats": { + "result_type": { + "name": "string_stats", + "type": "named" + } + }, + "value_count": { + "result_type": { + "name": "integer", + "type": "named" + } + } + }, + "comparison_operators": { + "match": { + "argument_type": { + "name": "keyword", + "type": "named" + }, + "type": "custom" + }, + "match_bool_prefix": { + "argument_type": { + "name": "keyword", + "type": "named" + }, + "type": "custom" + }, + "match_phrase": { + "argument_type": { + "name": "keyword", + "type": "named" + }, + "type": "custom" + }, + "prefix": { + "argument_type": { + "name": "keyword", + "type": "named" + }, + "type": "custom" + }, + "range": { + "argument_type": { + "name": "range", + "type": "named" + }, + "type": "custom" + }, + "regexp": { + "argument_type": { + "name": "keyword", + "type": "named" + }, + "type": "custom" + }, + "term": { + "type": "equal" + }, + "terms": { + "argument_type": { + "element_type": { + "name": "keyword", + "type": "named" + }, + "type": "array" + }, + "type": "custom" + }, + "wildcard": { + "argument_type": { + "name": "keyword", + "type": "named" + }, + "type": "custom" + } + }, + "representation": { + "type": "string" + } + }, + "long": { + "aggregate_functions": { + "avg": { + "result_type": { + "name": "long", + "type": "named" + } + }, + "cardinality": { + "result_type": { + "name": "integer", + "type": "named" + } + }, + "max": { + "result_type": { + "name": "long", + "type": "named" + } + }, + "min": { + "result_type": { + "name": "long", + "type": "named" + } + }, + "stats": { + "result_type": { + "name": "stats", + "type": "named" + } + }, + "sum": { + "result_type": { + "name": "long", + "type": "named" + } + }, + "value_count": { + "result_type": { + "name": "integer", + "type": "named" + } + } + }, + "comparison_operators": { + "match": { + "argument_type": { + "name": "long", + "type": "named" + }, + "type": "custom" + }, + "match_phrase": { + "argument_type": { + "name": "long", + "type": "named" + }, + "type": "custom" + }, + "range": { + "argument_type": { + "name": "range", + "type": "named" + }, + "type": "custom" + }, + "term": { + "type": "equal" + }, + "terms": { + "argument_type": { + "element_type": { + "name": "long", + "type": "named" + }, + "type": "array" + }, + "type": "custom" + } + }, + "representation": { + "type": "integer" + } + }, + "text": { + "aggregate_functions": {}, + "comparison_operators": { + "match": { + "argument_type": { + "name": "text", + "type": "named" + }, + "type": "custom" + }, + "match_bool_prefix": { + "argument_type": { + "name": "text", + "type": "named" + }, + "type": "custom" + }, + "match_phrase": { + "argument_type": { + "name": "text", + "type": "named" + }, + "type": "custom" + }, + "match_phrase_prefix": { + "argument_type": { + "name": "text", + "type": "named" + }, + "type": "custom" + }, + "prefix": { + "argument_type": { + "name": "text", + "type": "named" + }, + "type": "custom" + }, + "range": { + "argument_type": { + "name": "range", + "type": "named" + }, + "type": "custom" + }, + "regexp": { + "argument_type": { + "name": "text", + "type": "named" + }, + "type": "custom" + }, + "term": { + "type": "equal" + }, + "terms": { + "argument_type": { + "element_type": { + "name": "text", + "type": "named" + }, + "type": "array" + }, + "type": "custom" + }, + "wildcard": { + "argument_type": { + "name": "text", + "type": "named" + }, + "type": "custom" + } + }, + "representation": { + "type": "string" + } + }, + "text.keyword": { + "aggregate_functions": { + "cardinality": { + "result_type": { + "name": "integer", + "type": "named" + } + }, + "string_stats": { + "result_type": { + "name": "string_stats", + "type": "named" + } + }, + "value_count": { + "result_type": { + "name": "integer", + "type": "named" + } + } + }, + "comparison_operators": { + "match": { + "argument_type": { + "name": "keyword", + "type": "named" + }, + "type": "custom" + }, + "match_bool_prefix": { + "argument_type": { + "name": "keyword", + "type": "named" + }, + "type": "custom" + }, + "match_phrase": { + "argument_type": { + "name": "keyword", + "type": "named" + }, + "type": "custom" + }, + "prefix": { + "argument_type": { + "name": "keyword", + "type": "named" + }, + "type": "custom" + }, + "range": { + "argument_type": { + "name": "range", + "type": "named" + }, + "type": "custom" + }, + "regexp": { + "argument_type": { + "name": "keyword", + "type": "named" + }, + "type": "custom" + }, + "term": { + "type": "equal" + }, + "terms": { + "argument_type": { + "element_type": { + "name": "keyword", + "type": "named" + }, + "type": "array" + }, + "type": "custom" + }, + "wildcard": { + "argument_type": { + "name": "keyword", + "type": "named" + }, + "type": "custom" + } + }, + "representation": { + "type": "string" + } + } + } +} \ No newline at end of file diff --git a/testdata/unit_tests/query_tests/customers/configuration.json b/testdata/unit_tests/query_tests/customers/configuration.json new file mode 100644 index 0000000..4c92eb8 --- /dev/null +++ b/testdata/unit_tests/query_tests/customers/configuration.json @@ -0,0 +1,29 @@ +{ + "indices": { + "customers": { + "mappings": { + "properties": { + "customer_id": { + "type": "keyword" + }, + "email": { + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "fields": { + "raw": { + "ignore_above": 256, + "type": "keyword" + } + }, + "type": "text" + } + } + } + } + }, + "queries": {} +} \ No newline at end of file diff --git a/testdata/unit_tests/query_tests/customers/sort_by_subtype/ndc_request.json b/testdata/unit_tests/query_tests/customers/sort_by_subtype/ndc_request.json new file mode 100644 index 0000000..68c1395 --- /dev/null +++ b/testdata/unit_tests/query_tests/customers/sort_by_subtype/ndc_request.json @@ -0,0 +1,25 @@ +{ + "arguments": {}, + "collection": "customers", + "collection_relationships": {}, + "query": { + "fields": { + "name": { + "column": "name", + "type": "column" + } + }, + "order_by": { + "elements": [ + { + "order_direction": "asc", + "target": { + "name": "name", + "path": [], + "type": "column" + } + } + ] + } + } +} \ No newline at end of file diff --git a/testdata/unit_tests/query_tests/customers/sort_by_subtype/want.json b/testdata/unit_tests/query_tests/customers/sort_by_subtype/want.json new file mode 100644 index 0000000..d537cfe --- /dev/null +++ b/testdata/unit_tests/query_tests/customers/sort_by_subtype/want.json @@ -0,0 +1,13 @@ +{ + "_source": [ + "name" + ], + "size": 10000, + "sort": [ + { + "name.raw": { + "order": "asc" + } + } + ] +} \ No newline at end of file diff --git a/types/types.go b/types/types.go index 6449b1d..c3483ac 100644 --- a/types/types.go +++ b/types/types.go @@ -79,21 +79,16 @@ func (c *Configuration) GetFieldMap(indexName, fieldPath string) (map[string]int } // GetFieldProperties returns the field type, subtypes and field data enabled for the given field path. -func (c *Configuration) GetFieldProperties(indexName, fieldPath string) (fieldType string, fieldSubTypes []string, fieldDataEnabled bool, err error) { +func (c *Configuration) GetFieldProperties(indexName, fieldPath string) (fieldType string, subFieldMap map[string]string, fieldDataEnabled bool, err error) { fieldMap, err := c.GetFieldMap(indexName, fieldPath) if err != nil { return "", nil, false, err } - fieldsAndSubfields := internal.ExtractTypes(fieldMap) - + _, fieldType, subFieldMap = internal.ExtractTypes(fieldMap) fieldDataEnabled = internal.IsFieldDtaEnabled(fieldMap) - if len(fieldsAndSubfields) == 1 { - return fieldsAndSubfields[0], make([]string, 0), fieldDataEnabled, nil - } - - return fieldsAndSubfields[0], fieldsAndSubfields[1:], fieldDataEnabled, nil + return fieldType, subFieldMap, fieldDataEnabled, nil } // NativeQuery contains the definition of the native query. diff --git a/types/types_test.go b/types/types_test.go index 39f3b56..5ea5e66 100644 --- a/types/types_test.go +++ b/types/types_test.go @@ -194,7 +194,7 @@ func TestConfigurationGetFieldProperties(t *testing.T) { indexName string fieldPath string wantFieldType string - wantSubtypes []string + wantSubtypes map[string]string wantFieldDataEnabled bool }{ { @@ -203,7 +203,7 @@ func TestConfigurationGetFieldProperties(t *testing.T) { indexName: "customers", fieldPath: "name", wantFieldType: "text", - wantSubtypes: []string{"keyword"}, + wantSubtypes: map[string]string{"keyword": "keyword"}, wantFieldDataEnabled: false, }, { @@ -212,7 +212,7 @@ func TestConfigurationGetFieldProperties(t *testing.T) { indexName: "logs", fieldPath: "log_level", wantFieldType: "keyword", - wantSubtypes: []string{}, + wantSubtypes: map[string]string{}, wantFieldDataEnabled: false, }, { @@ -221,7 +221,7 @@ func TestConfigurationGetFieldProperties(t *testing.T) { indexName: "transactions", fieldPath: "transaction_details.item_name", wantFieldType: "text", - wantSubtypes: []string{"keyword"}, + wantSubtypes: map[string]string{"keyword":"keyword"}, wantFieldDataEnabled: false, }, { @@ -230,7 +230,7 @@ func TestConfigurationGetFieldProperties(t *testing.T) { indexName: "user_behavior", fieldPath: "actions", wantFieldType: "nested", - wantSubtypes: []string{}, + wantSubtypes: map[string]string{}, wantFieldDataEnabled: false, }, }