github.com/weaviate/weaviate@v1.24.6/test/modules/ref2vec-centroid/centroid_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  	"os"
    16  	"testing"
    17  
    18  	"github.com/go-openapi/strfmt"
    19  	"github.com/stretchr/testify/assert"
    20  	"github.com/weaviate/weaviate/entities/models"
    21  	"github.com/weaviate/weaviate/entities/schema/crossref"
    22  	"github.com/weaviate/weaviate/test/helper"
    23  	"github.com/weaviate/weaviate/test/helper/sample-schema/articles"
    24  )
    25  
    26  func TestCentroid(t *testing.T) {
    27  	helper.SetupClient(os.Getenv(weaviateEndpoint))
    28  
    29  	paragraphClass := articles.ParagraphsClass()
    30  	articleClass := articles.ArticlesClass()
    31  	articleClass.ModuleConfig = map[string]interface{}{
    32  		"ref2vec-centroid": map[string]interface{}{
    33  			"referenceProperties": []string{"hasParagraphs"},
    34  		},
    35  	}
    36  	articleClass.Vectorizer = "ref2vec-centroid"
    37  
    38  	helper.CreateClass(t, paragraphClass)
    39  	helper.CreateClass(t, articleClass)
    40  
    41  	defer func() {
    42  		helper.DeleteClass(t, articleClass.Class)
    43  		helper.DeleteClass(t, paragraphClass.Class)
    44  	}()
    45  
    46  	para1 := articles.NewParagraph().
    47  		WithVector([]float32{2, 4, 6}).
    48  		WithContents(
    49  			"Anyone who cares about JDM engines knows about the RB26.")
    50  	helper.CreateObject(t, para1.Object())
    51  
    52  	para2 := articles.NewParagraph().
    53  		WithVector([]float32{4, 6, 8}).
    54  		WithContents(
    55  			"It is best known for its use in the legendary Skyline GT-R.")
    56  	helper.CreateObject(t, para2.Object())
    57  
    58  	t.Run("create object with references", func(t *testing.T) {
    59  		t.Run("with one reference", func(t *testing.T) {
    60  			article := articles.NewArticle().
    61  				WithTitle("Popularity of the Nissan RB26DETT").
    62  				WithReferences(&models.SingleRef{
    63  					Beacon: newBeacon(para1.Class, para1.ID),
    64  				})
    65  			helper.CreateObject(t, article.Object())
    66  			defer helper.DeleteObject(t, article.Object())
    67  
    68  			res := helper.AssertGetObject(t, article.Class, article.ID, "vector")
    69  			assert.EqualValues(t, para1.Vector, res.Vector)
    70  		})
    71  
    72  		t.Run("with multiple references", func(t *testing.T) {
    73  			article := articles.NewArticle().
    74  				WithTitle("Popularity of the Nissan RB26DETT").
    75  				WithReferences(
    76  					&models.SingleRef{Beacon: newBeacon(para1.Class, para1.ID)},
    77  					&models.SingleRef{Beacon: newBeacon(para2.Class, para2.ID)},
    78  				)
    79  			helper.CreateObject(t, article.Object())
    80  			defer helper.DeleteObject(t, article.Object())
    81  
    82  			res := helper.AssertGetObject(t, article.Class, article.ID, "vector")
    83  			expectedVec := []float32{3, 5, 7}
    84  			assert.EqualValues(t, expectedVec, res.Vector)
    85  		})
    86  	})
    87  
    88  	t.Run("create object and PUT references", func(t *testing.T) {
    89  		article := articles.NewArticle().
    90  			WithTitle("Popularity of the Nissan RB26DETT")
    91  
    92  		helper.CreateObject(t, article.Object())
    93  		defer helper.DeleteObject(t, article.Object())
    94  
    95  		res := helper.AssertGetObject(t, article.Class, article.ID, "vector")
    96  		assert.Nil(t, res.Vector)
    97  		assert.Equal(t, article.ID, res.ID)
    98  
    99  		article.WithReferences(
   100  			&models.SingleRef{Beacon: newBeacon(para1.Class, para1.ID)},
   101  			&models.SingleRef{Beacon: newBeacon(para2.Class, para2.ID)},
   102  		)
   103  
   104  		helper.UpdateObject(t, article.Object())
   105  
   106  		res = helper.AssertGetObject(t, article.Class, article.ID, "vector")
   107  		assert.Equal(t, article.ID, res.ID)
   108  		expectedVec := []float32{3, 5, 7}
   109  		assert.EqualValues(t, expectedVec, res.Vector)
   110  	})
   111  
   112  	t.Run("create object with references, remove references", func(t *testing.T) {
   113  		ref1 := &models.SingleRef{Beacon: newBeacon(para1.Class, para1.ID)}
   114  		ref2 := &models.SingleRef{Beacon: newBeacon(para2.Class, para2.ID)}
   115  
   116  		article := articles.NewArticle().
   117  			WithTitle("Popularity of the Nissan RB26DETT").
   118  			WithReferences(ref1, ref2)
   119  		helper.CreateObject(t, article.Object())
   120  		defer helper.DeleteObject(t, article.Object())
   121  
   122  		res := helper.AssertGetObject(t, article.Class, article.ID, "vector")
   123  		expectedVec := []float32{3, 5, 7}
   124  		assert.EqualValues(t, expectedVec, res.Vector)
   125  
   126  		helper.DeleteReference(t, article.Object(), ref2, "hasParagraphs")
   127  		res = helper.AssertGetObject(t, article.Class, article.ID, "vector")
   128  		assert.EqualValues(t, para1.Vector, res.Vector)
   129  
   130  		helper.DeleteReference(t, article.Object(), ref1, "hasParagraphs")
   131  		res = helper.AssertGetObject(t, article.Class, article.ID, "vector")
   132  		assert.Nil(t, res.Vector)
   133  	})
   134  
   135  	t.Run("create object add references, remove references", func(t *testing.T) {
   136  		ref1 := &models.SingleRef{Beacon: newBeacon(para1.Class, para1.ID)}
   137  		ref2 := &models.SingleRef{Beacon: newBeacon(para2.Class, para2.ID)}
   138  
   139  		article := articles.NewArticle().
   140  			WithTitle("Popularity of the Nissan RB26DETT")
   141  		helper.CreateObject(t, article.Object())
   142  		defer helper.DeleteObject(t, article.Object())
   143  
   144  		res := helper.AssertGetObject(t, article.Class, article.ID, "vector")
   145  		assert.Nil(t, res.Vector)
   146  
   147  		helper.AddReference(t, article.Object(), ref1, "hasParagraphs")
   148  		res = helper.AssertGetObject(t, article.Class, article.ID, "vector")
   149  		assert.EqualValues(t, para1.Vector, res.Vector)
   150  
   151  		helper.AddReference(t, article.Object(), ref2, "hasParagraphs")
   152  		res = helper.AssertGetObject(t, article.Class, article.ID, "vector")
   153  		assert.EqualValues(t, []float32{3, 5, 7}, res.Vector)
   154  
   155  		helper.DeleteReference(t, article.Object(), ref1, "hasParagraphs")
   156  		res = helper.AssertGetObject(t, article.Class, article.ID, "vector")
   157  		assert.EqualValues(t, para2.Vector, res.Vector)
   158  
   159  		helper.DeleteReference(t, article.Object(), ref2, "hasParagraphs")
   160  		res = helper.AssertGetObject(t, article.Class, article.ID, "vector")
   161  		assert.Nil(t, res.Vector)
   162  	})
   163  
   164  	t.Run("batch create objects", func(t *testing.T) {
   165  		ref1 := &models.SingleRef{Beacon: newBeacon(para1.Class, para1.ID)}
   166  		ref2 := &models.SingleRef{Beacon: newBeacon(para2.Class, para2.ID)}
   167  
   168  		article1 := articles.NewArticle().
   169  			WithTitle("Popularity of the Nissan RB26DETT").
   170  			WithReferences(ref1, ref2)
   171  		defer helper.DeleteObject(t, article1.Object())
   172  
   173  		article2 := articles.NewArticle().
   174  			WithTitle("A Nissan RB Origin Story").
   175  			WithReferences(ref1, ref2)
   176  		defer helper.DeleteObject(t, article2.Object())
   177  
   178  		batch := []*models.Object{article1.Object(), article2.Object()}
   179  		helper.CreateObjectsBatch(t, batch)
   180  
   181  		res := helper.AssertGetObject(t, article1.Class, article1.ID, "vector")
   182  		assert.EqualValues(t, []float32{3, 5, 7}, res.Vector)
   183  		res = helper.AssertGetObject(t, article2.Class, article2.ID, "vector")
   184  		assert.EqualValues(t, []float32{3, 5, 7}, res.Vector)
   185  	})
   186  
   187  	// TODO: Uncomment when batch refs supports centroid re-calc
   188  	//t.Run("batch create references", func(t *testing.T) {
   189  	//	article := articles.NewArticle().
   190  	//		WithTitle("Popularity of the Nissan RB26DETT")
   191  	//	defer helper.DeleteObject(t, article.Object())
   192  	//
   193  	//	refs := []*models.BatchReference{
   194  	//		{
   195  	//			From: strfmt.URI(crossref.NewSource("Article", "hasParagraphs", article.ID).String()),
   196  	//			To:   strfmt.URI(crossref.NewLocalhost("Paragraph", para1.ID).String()),
   197  	//		},
   198  	//		{
   199  	//			From: strfmt.URI(crossref.NewSource("Article", "hasParagraphs", article.ID).String()),
   200  	//			To:   strfmt.URI(crossref.NewLocalhost("Paragraph", para2.ID).String()),
   201  	//		},
   202  	//	}
   203  	//
   204  	//	helper.AddReferences(t, refs)
   205  	//	res := helper.AssertGetObject(t, article.Class, article.ID, "vector")
   206  	//	assert.EqualValues(t, []float32{3, 5, 7}, res.Vector)
   207  	//})
   208  }
   209  
   210  func newBeacon(className string, id strfmt.UUID) strfmt.URI {
   211  	return crossref.New("localhost", className, id).SingleRef().Beacon
   212  }