Skip to content

Add support for FTS#2127

Open
emilienbev wants to merge 6 commits intomainfrom
AddFTS
Open

Add support for FTS#2127
emilienbev wants to merge 6 commits intomainfrom
AddFTS

Conversation

@emilienbev
Copy link
Copy Markdown
Collaborator

@emilienbev emilienbev commented Apr 7, 2026

Fixes #2085

Adds:

  • Template API: Added findBySearch to both standard and reactive templates, with builder for configuring index names, limits, sorting, facets, etc.
  • Search results are automatically converted to entities via KV Get. Stale documents are skipped.
  • Repository Support: @Search for query strings and @SearchIndex to specify index names.
  • SearchResult<T> wrapper to provide access to entities, metadata, and facets. Supports standard terminal operations like all(), first(), and count().
  • Added FTS support to @ScanConsistency and enabled Page/Slice for the non-reactive repository.
  • You have read the Spring Data contribution guidelines.
  • There is a ticket in the bug tracker for the project in our JIRA.
  • You use the code formatters provided here and have them applied to your changes. Don’t submit any formatting related changes.
  • You submit test cases (unit or integration tests) that back your changes.
  • You added yourself as author in the headers of the classes you touched. Amend the date range in the Apache license header if needed. For new types, add the license header (copy from another file and set the current year only).

@emilienbev emilienbev requested a review from Copilot April 7, 2026 09:04
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Apr 7, 2026

This comment was marked as outdated.

Fixes #2085

Signed-off-by: Emilien Bevierre <emilien.bevierre@couchbase.com>
…tites and totalRows in a single round trip

Signed-off-by: Emilien Bevierre <emilien.bevierre@couchbase.com>
Signed-off-by: Emilien Bevierre <emilien.bevierre@couchbase.com>
emilienbev and others added 3 commits April 9, 2026 12:05
Signed-off-by: Emilien Bevierre <emilien.bevierre@couchbase.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Emilien Bevierre <44171454+emilienbev@users.noreply.github.com>
Signed-off-by: Emilien Bevierre <emilien.bevierre@couchbase.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated 8 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
Comment on lines +76 to +78
void searchScanConsistencyAnnotationValueAttribute() {
// Verify the search attribute exists on the ScanConsistency annotation
ScanConsistency annotation = TestScanConsistencyRepository.class.getMethods()[0].getAnnotation(ScanConsistency.class);
Comment on lines +30 to +34
@Test
void searchAnnotationsAreRuntimeRetained() {
assertTrue(Search.class.isAnnotation());
assertTrue(SearchIndex.class.isAnnotation());
}
Comment on lines +20 to +32
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.junit.jupiter.api.Test;

import com.couchbase.client.java.search.HighlightStyle;
import com.couchbase.client.java.search.SearchOptions;
import com.couchbase.client.java.search.SearchRequest;
import com.couchbase.client.java.search.SearchQuery;
import com.couchbase.client.java.search.SearchScanConsistency;
import com.couchbase.client.java.search.facet.SearchFacet;
import com.couchbase.client.java.search.sort.SearchSort;
Comment on lines +72 to +86
@Override
public Object execute(Object[] parameters) {
ReactiveCouchbaseParameterAccessor accessor = new ReactiveCouchbaseParameterAccessor(method, parameters);

return accessor.resolveParameters().flatMapMany(resolvedAccessor -> {
ResultProcessor processor = method.getResultProcessor().withDynamicProjection(resolvedAccessor);
SearchRepositoryQuerySupport.validateSort(resolvedAccessor);

String resolvedQuery = SearchBasedCouchbaseQuery.resolveParameters(searchQueryTemplate, resolvedAccessor);
SearchRequest request = SearchRequest.create(SearchQuery.queryString(resolvedQuery));
Object result = executeDependingOnType(resolvedAccessor, request);

return ReactiveWrapperConverters.toWrapper(processor.processResult(result), reactor.core.publisher.Flux.class);
});
}
Comment on lines +82 to +89
cluster.searchIndexes().dropIndex(INDEX_NAME);
} catch (Exception e) {
LOGGER.warn("Failed to drop FTS index: {}", e.getMessage());
} finally {
logCluster(cluster, "tearDownFtsIndex");
}
callSuperAfterAll(new Object() {});
cluster.disconnect();
Comment on lines +344 to +353
if (i < maxRetries - 1 && (ex.getMessage().contains("no planPIndexes")
|| ex.getMessage().contains("pindex_consistency")
|| ex.getMessage().contains("pindex not available")
|| ex.getMessage().contains("index not found"))) {
sleepMs(2000);
continue;
}
if (i >= maxRetries - 1) {
throw new RuntimeException("FTS index " + indexName + " did not become ready in time", ex);
}
Comment on lines +96 to +105
private InsertedDoc insertRawDoc(String id, String firstname, String lastname) {
Collection col = couchbaseTemplate.getCouchbaseClientFactory().getDefaultCollection();
JsonObject content = JsonObject.create()
.put("id", id)
.put("firstname", firstname)
.put("lastname", lastname)
.put("t", "abstractuser"); // typeKey used by Config
MutationResult result = col.insert(id, content);
MutationState ms = MutationState.from(result.mutationToken().get());
return new InsertedDoc(id, ms);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: waiting-for-triage An issue we've not yet triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for FTS and Vector Search

3 participants