@@ -38,15 +38,15 @@ void vectorFunctionsHappyPath() {
3838 PlanBuilder .ModifyPlan plan =
3939 op .fromView ("vectors" , "persons" )
4040 .bind (op .as ("sampleVector" , op .vec .vector (sampleVector )))
41- .bind (op .as ("cosineSimilarity" , op .vec .cosineSimilarity (op .col ("embedding" ),op .col ("sampleVector" ))))
42- .bind (op .as ("dotProduct" , op .vec .dotProduct (op .col ("embedding" ),op .col ("sampleVector" ))))
43- .bind (op .as ("euclideanDistance" , op .vec .euclideanDistance (op .col ("embedding" ),op .col ("sampleVector" ))))
41+ .bind (op .as ("cosineSimilarity" , op .vec .cosineSimilarity (op .col ("embedding" ), op .col ("sampleVector" ))))
42+ .bind (op .as ("dotProduct" , op .vec .dotProduct (op .col ("embedding" ), op .col ("sampleVector" ))))
43+ .bind (op .as ("euclideanDistance" , op .vec .euclideanDistance (op .col ("embedding" ), op .col ("sampleVector" ))))
4444 .bind (op .as ("dimension" , op .vec .dimension (op .col ("sampleVector" ))))
4545 .bind (op .as ("normalize" , op .vec .normalize (op .col ("sampleVector" ))))
4646 .bind (op .as ("magnitude" , op .vec .magnitude (op .col ("sampleVector" ))))
4747 .bind (op .as ("get" , op .vec .get (op .col ("sampleVector" ), op .xs .integer (2 ))))
48- .bind (op .as ("add" , op .vec .add (op .col ("embedding" ),op .col ("sampleVector" ))))
49- .bind (op .as ("subtract" , op .vec .subtract (op .col ("embedding" ),op .col ("sampleVector" ))))
48+ .bind (op .as ("add" , op .vec .add (op .col ("embedding" ), op .col ("sampleVector" ))))
49+ .bind (op .as ("subtract" , op .vec .subtract (op .col ("embedding" ), op .col ("sampleVector" ))))
5050 .bind (op .as ("base64Encode" , op .vec .base64Encode (op .col ("sampleVector" ))))
5151 .bind (op .as ("base64Decode" , op .vec .base64Decode (op .col ("base64Encode" ))))
5252 .bind (op .as ("subVector" , op .vec .subvector (op .col ("sampleVector" ), op .xs .integer (1 ), op .xs .integer (1 ))))
@@ -64,15 +64,15 @@ void vectorFunctionsHappyPath() {
6464 rows .forEach (row -> {
6565// Simple a sanity checks to verify that the functions ran. Very little concern about the actual return values.
6666 double cosineSimilarity = row .getDouble ("cosineSimilarity" );
67- assertTrue ((cosineSimilarity > 0 ) && (cosineSimilarity < 1 ),"Unexpected value: " + cosineSimilarity );
67+ assertTrue ((cosineSimilarity > 0 ) && (cosineSimilarity < 1 ), "Unexpected value: " + cosineSimilarity );
6868 double dotProduct = row .getDouble ("dotProduct" );
6969 Assertions .assertTrue (dotProduct > 0 , "Unexpected value: " + dotProduct );
7070 double euclideanDistance = row .getDouble ("euclideanDistance" );
7171 Assertions .assertTrue (euclideanDistance > 0 , "Unexpected value: " + euclideanDistance );
7272 assertEquals (3 , row .getInt ("dimension" ));
7373 assertEquals (3 , ((ArrayNode ) row .get ("normalize" )).size ());
7474 double magnitude = row .getDouble ("magnitude" );
75- assertTrue ( magnitude > 0 , "Unexpected value: " + magnitude );
75+ assertTrue (magnitude > 0 , "Unexpected value: " + magnitude );
7676 assertEquals (3 , ((ArrayNode ) row .get ("add" )).size ());
7777 assertEquals (3 , ((ArrayNode ) row .get ("subtract" )).size ());
7878 assertFalse (row .getString ("base64Encode" ).isEmpty ());
@@ -89,7 +89,7 @@ void cosineSimilarity_DimensionMismatch() {
8989 PlanBuilder .ModifyPlan plan =
9090 op .fromView ("vectors" , "persons" )
9191 .bind (op .as ("sampleVector" , op .vec .vector (twoDimensionalVector )))
92- .bind (op .as ("cosineSimilarity" , op .vec .cosineSimilarity (op .col ("embedding" ),op .col ("sampleVector" ))))
92+ .bind (op .as ("cosineSimilarity" , op .vec .cosineSimilarity (op .col ("embedding" ), op .col ("sampleVector" ))))
9393 .select (op .col ("name" ), op .col ("summary" ), op .col ("cosineSimilarity" ));
9494 Exception exception = assertThrows (FailedRequestException .class , () -> resultRows (plan ));
9595 String actualMessage = exception .getMessage ();
@@ -102,7 +102,7 @@ void cosineSimilarity_InvalidVector() {
102102 PlanBuilder .ModifyPlan plan =
103103 op .fromView ("vectors" , "persons" )
104104 .bind (op .as ("sampleVector" , invalidVector ))
105- .bind (op .as ("cosineSimilarity" , op .vec .cosineSimilarity (op .col ("embedding" ),op .col ("sampleVector" ))))
105+ .bind (op .as ("cosineSimilarity" , op .vec .cosineSimilarity (op .col ("embedding" ), op .col ("sampleVector" ))))
106106 .select (op .col ("name" ), op .col ("summary" ), op .col ("cosineSimilarity" ));
107107 Exception exception = assertThrows (FailedRequestException .class , () -> resultRows (plan ));
108108 String actualMessage = exception .getMessage ();
@@ -111,20 +111,20 @@ void cosineSimilarity_InvalidVector() {
111111 }
112112
113113 @ Test
114- // As of 07/26/24, this test will fail with the ML12 develop branch.
115- // However, it will succeed with the 12ea1 build.
116- // See https://progresssoftware.atlassian.net/browse/MLE-15707
114+ // As of 07/26/24, this test will fail with the ML12 develop branch.
115+ // However, it will succeed with the 12ea1 build.
116+ // See https://progresssoftware.atlassian.net/browse/MLE-15707
117117 void bindVectorFromDocs () {
118118 PlanBuilder .ModifyPlan plan =
119119 op .fromSearchDocs (
120- op .cts .andQuery (
121- op .cts .documentQuery ("/optic/vectors/alice.json" ),
122- op .cts .elementQuery (
123- "person" ,
124- op .cts .trueQuery ()
125- )
126- ))
127- .bind (op .as ("embedding" , op .vec .vector (op .xpath ("doc" , "/person/embedding" ))));
120+ op .cts .andQuery (
121+ op .cts .documentQuery ("/optic/vectors/alice.json" ),
122+ op .cts .elementQuery (
123+ "person" ,
124+ op .cts .trueQuery ()
125+ )
126+ ))
127+ .bind (op .as ("embedding" , op .vec .vector (op .xpath ("doc" , "/person/embedding" ))));
128128 List <RowRecord > rows = resultRows (plan );
129129 assertEquals (1 , rows .size ());
130130 }
@@ -138,4 +138,30 @@ void vecVectorWithCol() {
138138 List <RowRecord > rows = resultRows (plan );
139139 assertEquals (2 , rows .size ());
140140 }
141+
142+ @ Test
143+ void annTopK () {
144+ PlanBuilder .ModifyPlan plan = op .fromView ("vectors" , "persons" )
145+ .annTopK (10 , op .col ("embedding" ), op .vec .vector (sampleVector ), op .col ("distance" ), 0.5f );
146+
147+ List <RowRecord > rows = resultRows (plan );
148+ assertEquals (2 , rows .size (), "Verifying that annTopK worked and returned both rows from the view." );
149+
150+ rows .forEach (row -> {
151+ float distance = row .getFloat ("distance" );
152+ assertTrue (distance > 0 , "Just verifying that annTopK both worked and put a valid value into the 'distance' column." );
153+ });
154+ }
155+
156+ @ Test
157+ void dslAnnTopK () {
158+ String query = "const qualityVector = vec.vector([ 1.1, 2.2, 3.3 ]);\n " +
159+ "op.fromView('vectors', 'persons')\n " +
160+ " .bind(op.as('myVector', op.vec.vector(op.col('embedding'))))\n " +
161+ " .annTopK(2, op.col('myVector'), qualityVector, op.col('distance'), 0.5)" ;
162+
163+ RawQueryDSLPlan plan = rowManager .newRawQueryDSLPlan (new StringHandle (query ));
164+ List <RowRecord > rows = resultRows (plan );
165+ assertEquals (2 , rows .size (), "Just verifying that 'annTopK' works via the DSL and v1/rows." );
166+ }
141167}
0 commit comments