github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/crud_noindex_property_integration_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  //go:build integrationTest
    13  // +build integrationTest
    14  
    15  package db
    16  
    17  import (
    18  	"context"
    19  	"testing"
    20  
    21  	"github.com/go-openapi/strfmt"
    22  	"github.com/sirupsen/logrus/hooks/test"
    23  	"github.com/stretchr/testify/assert"
    24  	"github.com/stretchr/testify/require"
    25  	"github.com/weaviate/weaviate/entities/additional"
    26  	"github.com/weaviate/weaviate/entities/dto"
    27  	"github.com/weaviate/weaviate/entities/filters"
    28  	"github.com/weaviate/weaviate/entities/models"
    29  	"github.com/weaviate/weaviate/entities/schema"
    30  	"github.com/weaviate/weaviate/entities/search"
    31  	enthnsw "github.com/weaviate/weaviate/entities/vectorindex/hnsw"
    32  )
    33  
    34  func TestCRUD_NoIndexProp(t *testing.T) {
    35  	dirName := t.TempDir()
    36  
    37  	vFalse := false
    38  	logger, _ := test.NewNullLogger()
    39  	thingclass := &models.Class{
    40  		Class:               "ThingClassWithNoIndexProps",
    41  		VectorIndexConfig:   enthnsw.NewDefaultUserConfig(),
    42  		InvertedIndexConfig: invertedConfig(),
    43  		Properties: []*models.Property{{
    44  			Name:         "stringProp",
    45  			DataType:     schema.DataTypeText.PropString(),
    46  			Tokenization: models.PropertyTokenizationWhitespace,
    47  		}, {
    48  			Name:            "hiddenStringProp",
    49  			DataType:        schema.DataTypeText.PropString(),
    50  			Tokenization:    models.PropertyTokenizationWhitespace,
    51  			IndexFilterable: &vFalse,
    52  			IndexSearchable: &vFalse,
    53  		}},
    54  	}
    55  	schemaGetter := &fakeSchemaGetter{
    56  		schema:     schema.Schema{Objects: &models.Schema{Classes: nil}},
    57  		shardState: singleShardState(),
    58  	}
    59  	repo, err := New(logger, Config{
    60  		RootPath:                  dirName,
    61  		QueryMaximumResults:       10000,
    62  		MaxImportGoroutinesFactor: 1,
    63  		MemtablesFlushDirtyAfter:  60,
    64  	}, &fakeRemoteClient{}, &fakeNodeResolver{}, &fakeRemoteNodeClient{}, &fakeReplicationClient{}, nil)
    65  	require.Nil(t, err)
    66  	repo.SetSchemaGetter(schemaGetter)
    67  	require.Nil(t, repo.WaitForStartup(testCtx()))
    68  	defer repo.Shutdown(context.Background())
    69  
    70  	migrator := NewMigrator(repo, logger)
    71  
    72  	t.Run("creating the thing class", func(t *testing.T) {
    73  		require.Nil(t,
    74  			migrator.AddClass(context.Background(), thingclass, schemaGetter.shardState))
    75  
    76  		// update schema getter so it's in sync with class
    77  		schemaGetter.schema = schema.Schema{
    78  			Objects: &models.Schema{
    79  				Classes: []*models.Class{thingclass},
    80  			},
    81  		}
    82  	})
    83  
    84  	thingID := strfmt.UUID("9f119c4f-80da-4ae5-bfd1-e4b63054125f")
    85  
    86  	t.Run("adding a thing", func(t *testing.T) {
    87  		thing := &models.Object{
    88  			CreationTimeUnix:   1565612833955,
    89  			LastUpdateTimeUnix: 1000001,
    90  			ID:                 thingID,
    91  			Class:              "ThingClassWithNoIndexProps",
    92  			Properties: map[string]interface{}{
    93  				"stringProp":       "some value",
    94  				"hiddenStringProp": "some hidden value",
    95  			},
    96  		}
    97  		vector := []float32{1, 3, 5, 0.4}
    98  		err := repo.PutObject(context.Background(), thing, vector, nil, nil)
    99  
   100  		assert.Nil(t, err)
   101  	})
   102  
   103  	t.Run("all props are present when getting by id", func(t *testing.T) {
   104  		res, err := repo.ObjectByID(context.Background(), thingID, search.SelectProperties{}, additional.Properties{}, "")
   105  		expectedSchema := map[string]interface{}{
   106  			"stringProp":       "some value",
   107  			"hiddenStringProp": "some hidden value",
   108  			"id":               thingID,
   109  		}
   110  
   111  		require.Nil(t, err)
   112  		assert.Equal(t, expectedSchema, res.Schema)
   113  	})
   114  
   115  	// Same as above, but with Object()
   116  	t.Run("all props are present when getting by id and class", func(t *testing.T) {
   117  		res, err := repo.Object(context.Background(), "ThingClassWithNoIndexProps", thingID,
   118  			search.SelectProperties{}, additional.Properties{}, nil, "")
   119  		expectedSchema := map[string]interface{}{
   120  			"stringProp":       "some value",
   121  			"hiddenStringProp": "some hidden value",
   122  			"id":               thingID,
   123  		}
   124  
   125  		require.Nil(t, err)
   126  		assert.Equal(t, expectedSchema, res.Schema)
   127  	})
   128  
   129  	t.Run("class search on the noindex prop errors", func(t *testing.T) {
   130  		_, err := repo.Search(context.Background(), dto.GetParams{
   131  			ClassName: "ThingClassWithNoIndexProps",
   132  			Pagination: &filters.Pagination{
   133  				Limit: 10,
   134  			},
   135  			Filters: buildFilter("hiddenStringProp", "hidden", eq, schema.DataTypeText),
   136  		})
   137  
   138  		require.NotNil(t, err)
   139  		assert.Contains(t, err.Error(), "Filtering by property 'hiddenStringProp' requires inverted index. "+
   140  			"Is `indexFilterable` option of property 'hiddenStringProp' enabled? "+
   141  			"Set it to `true` or leave empty")
   142  	})
   143  
   144  	t.Run("class search on timestamp prop with no timestamp indexing error", func(t *testing.T) {
   145  		_, err := repo.Search(context.Background(), dto.GetParams{
   146  			ClassName: "ThingClassWithNoIndexProps",
   147  			Pagination: &filters.Pagination{
   148  				Limit: 10,
   149  			},
   150  			Filters: buildFilter("_creationTimeUnix", "1234567891011", eq, schema.DataTypeText),
   151  		})
   152  
   153  		require.NotNil(t, err)
   154  		assert.Contains(t, err.Error(),
   155  			"Timestamps must be indexed to be filterable! Add `IndexTimestamps: true` to the InvertedIndexConfig in")
   156  	})
   157  }