4444import com .couchbase .client .java .search .SearchQuery ;
4545import com .couchbase .client .java .search .SearchRequest ;
4646import com .couchbase .client .java .search .facet .SearchFacet ;
47+ import com .couchbase .client .java .search .result .SearchMetrics ;
4748import com .couchbase .client .java .search .result .SearchRow ;
4849import com .couchbase .client .java .search .sort .SearchSort ;
4950
@@ -96,7 +97,6 @@ static void setupFtsTest() {
9697
9798 @ AfterAll
9899 public static void tearDownFtsTest () {
99- // Index is intentionally NOT dropped: re-indexing 30k+ docs on each run is too slow.
100100 if (travelSampleClientFactory != null ) {
101101 try {
102102 travelSampleClientFactory .close ();
@@ -142,7 +142,7 @@ void searchCountForKnownCountry() {
142142 .matching (airportSearch (SearchQuery .match ("United States" ).field ("country" )))
143143 .count ();
144144
145- assertTrue ( count > 100 , "Expected many US airports in travel-sample " );
145+ assertEquals ( 1747 , count , "travel-sample airports matching the 'United States' analyzed query " );
146146 }
147147
148148 @ Test
@@ -216,12 +216,30 @@ void searchResultCombinesEntitiesAndMetadata() {
216216
217217 assertNotNull (result );
218218 assertEquals (3 , result .entities ().size (), "Should have 3 hydrated entities" );
219- assertTrue ( result .totalRows () > 3 , "Total rows should exceed the limit" );
219+ assertEquals ( 1968 , result .totalRows (), "travel-sample has 1968 airports; total rows is independent of the limit" );
220220 assertNotNull (result .metaData (), "Metadata should be present" );
221221 assertFalse (result .facets ().isEmpty (), "Facet results should be present" );
222222 assertTrue (result .facets ().containsKey ("countries" ));
223223 }
224224
225+ @ Test
226+ void searchResultExposesMetrics () {
227+ SearchResult <TsAirport > result = template .findBySearch (TsAirport .class )
228+ .withIndex (INDEX_NAME )
229+ .withLimit (10 )
230+ .matching (airportSearch (SearchQuery .match ("international" ).field ("airportname" )))
231+ .result ();
232+
233+ SearchMetrics metrics = result .metaData ().metrics ();
234+ assertEquals (20 , metrics .totalRows (), "travel-sample has 20 airports named 'international'" );
235+ assertEquals (6.915073962015045 , result .maxScore (), 1e-6 , "Max BM25 score for the query" );
236+ assertFalse (metrics .took ().isNegative (), "Execution time should not be negative" );
237+ assertTrue (metrics .totalPartitionCount () > 0 , "Should have queried at least one partition" );
238+ assertEquals (metrics .totalPartitionCount (), metrics .successPartitionCount (),
239+ "All partitions should have succeeded" );
240+ assertEquals (0 , metrics .errorPartitionCount (), "No partition should have errored" );
241+ }
242+
225243 @ Test
226244 void searchWithSortByScoreDescending () {
227245 List <SearchRow > rows = template .findBySearch (TsAirport .class )
@@ -255,8 +273,6 @@ void reactiveSearchReturnsHydratedEntities() {
255273 }
256274 }
257275
258- // --- Domain entity for travel-sample airports ---
259-
260276 @ Scope ("inventory" )
261277 @ Collection ("airport" )
262278 static class TsAirport {
@@ -269,7 +285,7 @@ static class TsAirport {
269285 String tz ;
270286 }
271287
272- // --- Helpers ---
288+ // Helpers
273289
274290 private static void ensureFtsIndex (Cluster cluster ) {
275291 com .couchbase .client .java .Scope scope = cluster .bucket (TS_BUCKET ).scope ("inventory" );
@@ -285,7 +301,6 @@ private static void ensureFtsIndex(Cluster cluster) {
285301 }
286302
287303 private static void waitForFtsIndex (com .couchbase .client .java .Scope scope ) {
288- // Phase 1: wait for the index to be queryable
289304 for (int i = 0 ; i < 30 ; i ++) {
290305 try {
291306 scope .search (INDEX_NAME , SearchRequest .create (SearchQuery .matchAll ()));
@@ -296,7 +311,7 @@ private static void waitForFtsIndex(com.couchbase.client.java.Scope scope) {
296311 sleepMs (2000 );
297312 }
298313 }
299- // Phase 2: wait for documents to be indexed
314+
300315 for (int i = 0 ; i < 60 ; i ++) {
301316 try {
302317 long docCount = scope .searchIndexes ().getIndexedDocumentsCount (INDEX_NAME );
0 commit comments