github.com/weaviate/weaviate@v1.24.6/usecases/traverser/hybrid/fusion_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 hybrid 13 14 import ( 15 "fmt" 16 "testing" 17 18 "github.com/stretchr/testify/require" 19 20 "github.com/go-openapi/strfmt" 21 "github.com/stretchr/testify/assert" 22 "github.com/weaviate/weaviate/entities/search" 23 ) 24 25 func TestFusionRelativeScore(t *testing.T) { 26 cases := []struct { 27 weights []float64 28 inputScores [][]float32 29 expectedScores []float32 30 expectedOrder []uint64 31 }{ 32 {weights: []float64{0.5, 0.5}, inputScores: [][]float32{{1, 2, 3}, {0, 1, 2}}, expectedScores: []float32{1, 0.5, 0}, expectedOrder: []uint64{2, 1, 0}}, 33 {weights: []float64{0.5, 0.5}, inputScores: [][]float32{{0, 2, 0.1}, {0, 0.2, 2}}, expectedScores: []float32{0.55, 0.525, 0}, expectedOrder: []uint64{1, 2, 0}}, 34 {weights: []float64{0.75, 0.25}, inputScores: [][]float32{{0.5, 0.5, 0}, {0, 0.01, 0.001}}, expectedScores: []float32{1, 0.75, 0.025}, expectedOrder: []uint64{1, 0, 2}}, 35 {weights: []float64{0.75, 0.25}, inputScores: [][]float32{{}, {}}, expectedScores: []float32{}, expectedOrder: []uint64{}}, 36 {weights: []float64{0.75, 0.25}, inputScores: [][]float32{{1}, {}}, expectedScores: []float32{0.75}, expectedOrder: []uint64{0}}, 37 {weights: []float64{0.75, 0.25}, inputScores: [][]float32{{}, {1}}, expectedScores: []float32{0.25}, expectedOrder: []uint64{0}}, 38 {weights: []float64{0.75, 0.25}, inputScores: [][]float32{{1, 2}, {}}, expectedScores: []float32{0.75, 0}, expectedOrder: []uint64{1, 0}}, 39 {weights: []float64{0.75, 0.25}, inputScores: [][]float32{{}, {1, 2}}, expectedScores: []float32{0.25, 0}, expectedOrder: []uint64{1, 0}}, 40 {weights: []float64{0.75, 0.25}, inputScores: [][]float32{{1, 1}, {1, 2}}, expectedScores: []float32{1, 0.75}, expectedOrder: []uint64{1, 0}}, 41 {weights: []float64{1}, inputScores: [][]float32{{1, 2, 3}}, expectedScores: []float32{1, 0.5, 0}, expectedOrder: []uint64{2, 1, 0}}, 42 {weights: []float64{0.75, 0.25}, inputScores: [][]float32{{1, 2, 3, 4}, {1, 2, 3}}, expectedScores: []float32{0.75, 0.75, 0.375, 0}, expectedOrder: []uint64{3, 2, 1, 0}}, 43 } 44 for _, tt := range cases { 45 t.Run("hybrid fusion", func(t *testing.T) { 46 var results [][]*search.Result 47 for i := range tt.inputScores { 48 var result []*search.Result 49 for j, score := range tt.inputScores[i] { 50 docId := uint64(j) 51 result = append(result, &search.Result{SecondarySortValue: score, DocID: &docId, ID: strfmt.UUID(fmt.Sprint(j))}) 52 } 53 results = append(results, result) 54 } 55 fused := FusionRelativeScore(tt.weights, results, []string{"set1", "set2"}) 56 fusedScores := []float32{} // don't use nil slice declaration, should be explicitly empty 57 fusedOrder := []uint64{} 58 59 for _, score := range fused { 60 fusedScores = append(fusedScores, score.Score) 61 fusedOrder = append(fusedOrder, *score.DocID) 62 } 63 64 assert.InDeltaSlice(t, tt.expectedScores, fusedScores, 0.0001) 65 assert.Equal(t, tt.expectedOrder, fusedOrder) 66 }) 67 } 68 } 69 70 func TestFusionRelativeScoreExplain(t *testing.T) { 71 docId1 := uint64(1) 72 docId2 := uint64(2) 73 result1 := []*search.Result{ 74 {DocID: &docId1, SecondarySortValue: 0.5, ID: strfmt.UUID(fmt.Sprint(1))}, 75 {DocID: &docId2, SecondarySortValue: 0.1, ID: strfmt.UUID(fmt.Sprint(2))}, 76 } 77 78 result2 := []*search.Result{ 79 {DocID: &docId1, SecondarySortValue: 2, ID: strfmt.UUID(fmt.Sprint(1))}, 80 {DocID: &docId2, SecondarySortValue: 1, ID: strfmt.UUID(fmt.Sprint(2))}, 81 } 82 results := [][]*search.Result{result1, result2} 83 fused := FusionRelativeScore([]float64{0.5, 0.5}, results, []string{"keyword", "vector"}) 84 require.Contains(t, fused[0].ExplainScore, "(Result Set keyword) Document 1: original score 0.5, normalized score: 0.5") 85 require.Contains(t, fused[0].ExplainScore, "(Result Set vector) Document 1: original score 2, normalized score: 0.5") 86 }