Vector Search
Vector Search from the SDK, to enable AI integration, semantic search, and use of RAG frameworks.
Vector Search has been available in Couchbase Capella Operational and self-managed Server since version 7.6, using the Couchbase Search Service. Version 8.0 introduces vector query using Global Secondary Indexes (GSI), the Query Service index — using either a fast Hyperscale index, or a composite index to combine scalar queries with semantic search.
For fast and scalable vector queries, use one of the above two GSI choices — detailed in the next section. If you don’t require the speed and scale of vector query with GSI, or need to combine vector, geo-spatial search, range search, and traditional fuzzy text searches, then consider Vector Search With the Search Service.
Vector Search With the Query Service and GSI
From the SDK, a vector query using GSI is the same as any other query. However, you will need to build one or more indexes.
Prerequisites
-
Couchbase Server 8.0.0 or newer — or a recent Capella instance.
-
Your chosen vector index — hyperscale or composite.
You will need to refer to the Use Vector Indexes for AI Applications pages for a full discussion of using Vector Indexes with Vector Queries. In particular, you will need to create a Vector Index.
Examples
The Use Vector Indexes for AI Applications pages contain examples using both hyperscale and compound indexes.
Here is the Hyperscale Index example, wrapped inside the C++ SDK Query API.
auto [err, res] =
cluster
.query(
"SELECT d.id, d.question, d.wanted_similar_color_from_search, "
" ARRAY_CONCAT( "
"d.couchbase_search_query.knn[0].vector[0:4], "
"['...'] "
") AS vector "
"FROM `vector-sample`.`color`.`rgb-questions` AS d "
"WHERE d.id = '#87CEEB';",
couchbase::query_options().metrics(true)
)
.get();
if (err) {
fmt::println("Error: {}", err);
} else {
auto rows = res.rows_as<couchbase::codec::tao_json_serializer>();
for (const auto& row : rows) {
fmt::println("Row: {}", tao::json::to_string(row));
}
}
Parameterizing the query, as with regular queries, will allow the reuse of the Query Plan. This can be more efficient, unless you are doing a lot of optimization to your query.
auto [err, res] =
cluster
.query(
"SELECT d.id, d.question, d.wanted_similar_color_from_search, "
" ARRAY_CONCAT( "
"d.couchbase_search_query.knn[0].vector[0:4], "
"['...'] "
") AS vector "
"FROM `vector-sample`.`color`.`rgb-questions` AS d "
"WHERE d.id = $id;",
couchbase::query_options().named_parameters(std::make_pair("id", "#87CEEB"))
)
.get();
if (err) {
fmt::println("Error: {}", err);
} else {
auto rows = res.rows_as<couchbase::codec::tao_json_serializer>();
for (const auto& row : rows) {
fmt::println("Row: {}", tao::json::to_string(row));
}
}
Vector Search With the Search Service
Vector search is also implemented using Search Indexes, and can be combined with traditional full text search queries. Vector embeddings can be an array of floats or a base64 encoded string.
Prerequisites
Couchbase Server 7.6.0 (7.6.2 for base64-encoded vectors) — or recent Capella instance.
Examples
Single vector query
In this first example we are performing a single vector query:
couchbase::search_request request(couchbase::vector_search(couchbase::vector_query("vector_field", vector_query)));
auto [err, res] = scope.search("vector-index", request).get();
Let’s break this down.
We create a search_request, which can contain a traditional FTS query search_query and/or the new vector_search.
Here we are just using the latter.
The vector_search allows us to perform one or more vector_query s.
The vector_query itself takes the name of the document field that contains embedded vectors ("vector_field" here), plus actual vector query in the form of a std::vector<double>.
(Note that Couchbase itself is not involved in generating the vectors, and these will come from an external source such as an embeddings API.)
Finally we execute the search_request against the FTS index "vector-index", which has previously been setup to vector index the "vector_field" field.
This happens to be a scoped index so we are using scope.search().
If it was a global index we would use cluster.search() instead - see [Scoped vs Global Indexes].
It returns the same search_result detailed earlier.
Pre-Filters
From Couchbase Server 7.6.4 — and in Capella Operational clusters — pre-filtering with similarity search is available. This is a non-vector query that the server executes first to get an intermediate result. Then it executes the vector query on the intermediate result to get the final result.
template<typename SearchQuery>
auto prefilter(SearchQuery prefilter) -> couchbase::vector_query&
If no prefilter is specified, the server executes the vector query on all indexed documents.
couchbase::vector_query("vector_field", vector_query)
.num_candidates(num_candidates)
.prefilter(couchbase::match_query("primary")
.field("color_wheel_pos"))
The prefilter can be any Search Query — from a simple match, as above, to a string query:
.prefilter(couchbase::query_string_query("+description:sea -color_hex:fff5ee"))
See the API reference.
Multiple vector queries
You can run multiple vector queries together:
std::vector<couchbase::vector_query> vector_queries{
couchbase::vector_query("vector_field", vector_query).num_candidates(2).boost(0.3),
couchbase::vector_query("vector_field", another_vector_query).num_candidates(5).boost(0.7)
};
auto request = couchbase::search_request(couchbase::vector_search(vector_queries));
auto [err, res] = scope.search("vector-index", request).get();
How the results are combined (ANDed or ORed) can be controlled with vector_search_options.query_combination().
Combining FTS and vector queries
You can combine a traditional FTS query with vector queries:
auto request = couchbase::search_request(couchbase::match_all_query())
.vector_search(couchbase::vector_search(couchbase::vector_query("vector_field", vector_query)));
auto [err, res] = scope.search("vector-and-fts-index", request).get();
How the results are combined (ANDed or ORed) can be controlled with vector_search_options.query_combination().
Further Reading
Vector Query
-
Vector Query for AI Apps docs (self-managed Couchbase Server).
-
Vector GSI Query is just like any other query from the SDK to the Query service: C++ SDK API Reference.