Skip to main content

Brute-force kNN

UDTF: cuvs_brute_force_knn

Official cuVS reference: C API

Exact brute-force nearest-neighbor search over dense vectors.

Quickstart​

The call below expects the registered relations dataset_vectors (the dataset role) and query_vectors (the queries role), each passed as a parenthesized SELECT subquery. Substitute your own relations and column names.

SELECT *
FROM cuvs_brute_force_knn(
dataset => (SELECT id, d0, d1 FROM dataset_vectors),
queries => (SELECT id, d0, d1 FROM query_vectors),
k => 8,
metric => 'l2_expanded'
);

Inputs​

Each relation argument is a parenthesized SELECT subquery that the planner keeps as a real child; metadata validation resolves a registered table or view for the same role instead. See Vector Inputs for the relation identity rules and the ID, dense-vector type, null, finite-value, and runtime-dimension contract.

RoleRequiredValidation referenceDescription
datasetyestableDense-vector rows indexed for nearest-neighbor search.
queriesyestableDense-vector query rows matched against the evaluated dataset.

Vector element types​

Element typeValid metrics
Float32l2_expanded, l2_sqrt_expanded, cosine, inner_product

Arguments and options​

Scalar SQL arguments​

ArgumentTypeRequiredDescription
kintegeryesNumber of neighbors returned for each evaluated query row.
metricenum ("l2_expanded", "l2_sqrt_expanded", "cosine", "inner_product")yesDistance or score metric. Distance metrics rank lower values first; inner product ranks higher values first.

SQL value argument schemas​

ArgumentRequiredLiteral shapeDefaultConstraintsDescription
kyesintegerNo defaultminimum 1; maximum 4294967295Number of neighbors returned for each evaluated query row.
metricyesstringNo defaultone of "l2_expanded", "l2_sqrt_expanded", "cosine", "inner_product"Distance or score metric. Distance metrics rank lower values first; inner product ranks higher values first. Supported element/metric combinations: Float32: l2_expanded, l2_sqrt_expanded, cosine, inner_product.

Vector binding shapes​

Each relation subquery must project a non-null id field followed by either one or more non-null feature fields of a supported element type (Float32) or one non-null list vector field named vector.

For wide vectors, the projection order defines the feature dimensions. A list vector relation must contain no feature field beside id and vector.

Output​

ColumnTypeNullableDescription
query_ordinalUInt64noZero-based ordinal of the evaluated query row; it disambiguates duplicate query IDs.
query_idsame_as_queries.idnoLogical ID copied from the queries relation.
neighbor_ordinalUInt64noZero-based ordinal of the matched dataset row; it disambiguates duplicate dataset IDs.
neighbor_idsame_as_dataset.idnoLogical ID copied from the matched dataset row.
rankUInt32noOne-based neighbor rank within a query. Order consumers explicitly by query_ordinal, rank.
distanceFloat32noMetric value; smaller is better for distance metrics, while inner_product prefers larger values.

Concrete schemas are call-specific. Run gpu_validate_call against registered relations to inspect the output schema after the actual ID types and literal options are validated.

Examples​

This example uses the Amazon Reviews demo dataset.

Which travel headphones meet our price and review-history criteria?​

A merchandising analyst needs a shortlist for long flights. The request is “Wireless noise cancelling over ear headphones for long airplane flights.” The candidate must also cost $20–150 in the catalog snapshot, have at least 100 verified-purchase reviews in 2022, and have at most 20% reviews rated at most two stars in that period.

The query computes those review statistics from the complete reviews table and joins them to the product catalog before nearest-neighbor search. The 117 eligible products become the search dataset. Changing the year or the rating threshold changes that dataset within the statement.

WITH review_history AS (
SELECT product_id, COUNT(*) AS reviews_2022,
AVG(CASE WHEN rating <= 2 THEN 1.0 ELSE 0.0 END) AS low_rating_share
FROM reviews
WHERE review_time >= TIMESTAMP '2022-01-01'
AND review_time < TIMESTAMP '2023-01-01' AND verified_purchase
GROUP BY product_id
), eligible AS (
SELECT v.id, v.vector
FROM semantic_products_vectors v
JOIN products p ON p.product_id = v.id
JOIN review_history h ON h.product_id = v.id
WHERE v.sample_rank < 1000000
AND p.category_l3 = 'Headphones & Earbuds'
AND p.price BETWEEN 20 AND 150
AND h.reviews_2022 >= 100 AND h.low_rating_share <= 0.20
)
SELECT n.rank, p.product_id, p.title, p.price,
h.reviews_2022, h.low_rating_share,
1.0 - n.distance / 2.0 AS cosine_similarity
FROM cuvs_brute_force_knn(
dataset => (SELECT id, vector FROM eligible),
queries => (SELECT id, vector FROM intent_queries WHERE id = 0),
k => 10, metric => 'l2_expanded') n
JOIN products p ON p.product_id = n.neighbor_id
JOIN review_history h ON h.product_id = p.product_id
ORDER BY n.rank;

The query vector is row id = 0 in intent_queries, prepared with BGE-M3 from the request above. Stored product and query vectors are normalized; 1 - squared_L2 / 2 therefore gives cosine similarity. SQL enriches each neighbor with the same review statistics used to admit the candidate.

The first five rows of the 2026-09-28 capture are below. Product names are shortened; the capture metadata and result rows retain their IDs and complete titles.

RankProductSnapshot priceVerified reviews, 2022Low-rating shareCosine similarity
1Srhythm NC35$69.9935316.15%0.6392
2VELKPRO office headset$29.991035.83%0.6105
3HROEENOI over-ear ANC headphones$45.9935417.51%0.6034
4Soundcore Space Q45$149.9917911.73%0.5999
5PurelySound E7$39.4831014.19%0.5995

The office headset in second place meets the SQL conditions, but its title describes on-ear office use. A catalog reviewer can reject it on that basis while keeping the price and review-history evidence attached to the other candidates. The complete statement took a median 1.54 seconds over three runs; capture conditions include index construction and Flight result transfer.

The shortlist supports catalog review. A high similarity score does not establish wireless connectivity, over-ear fit or effective noise cancellation; those requirements still need product-specification checks. Catalog prices are historical, and the low-rating share is a fraction of reviews, not a failure rate.

Refresh similar-product candidates for a batch of catalog entries​

A batch comparison uses one million catalog vectors and 10,000 disjoint query products, each with 1,024 dimensions. This statement returns ten neighbors for each query product:

SELECT n.query_id, q.title AS source_title, n.rank,
n.neighbor_id, p.title AS candidate_title,
1.0 - n.distance / 2.0 AS cosine_similarity
FROM cuvs_brute_force_knn(
dataset => (SELECT * FROM product_corpus_1000000),
queries => (SELECT * FROM product_queries_10000),
k => 10, metric => 'l2_expanded') n
JOIN semantic_products_text q ON q.id = n.query_id
JOIN semantic_products_text p ON p.id = n.neighbor_id
ORDER BY n.query_id, n.rank;

The output can seed a catalog editor's comparison queue. Matching text does not establish that two listings describe the same item or interchangeable products. The index is built within each statement, including when the input is a view.

The capture returned 100,000 rows in a median 2.58 seconds over three runs. For source product 1248764, a midnight-blue Sony WH-1000XM4 listing, the first candidates illustrate why the result is useful for human comparison:

RankCandidate product IDShortened titleCosine similarity
11271346Sony WH-1000XM4, black, renewed0.9513
21548411Sony WH-1000XM4 bundle with case, charger and gym bag0.9046
31267625Sony WH-1000XM4, silver, bundle with battery bank0.8836

The candidates share the headphone model while differing in condition, color or included items. An editor can inspect those differences before merging listings or presenting alternatives.

Float32 l2_expanded can round near-identical vectors to zero distance. In the separate 100,000-neighbor verification, three reported zeros had positive Float64 distances, at most 0.0002202. A zero distance alone does not establish a duplicate listing.

Limits​

  • Validation resolves named tables or views and reads schemas only; it does not execute relation scans or GPU work.
  • Execution relation arguments require parenthesized subqueries; dry-run validation accepts registered named relations only.
  • Builds an exact query-local index over the evaluated dataset relation; it does not persist an ANN index or replace a vector database.
  • The evaluated dataset must be non-empty and k must not exceed its row count. An empty query relation may return an empty result with the stable schema.
  • Dataset and query vector dimensions must match after both relation children are evaluated.

To dry-run validate relation metadata, column types, and options without execution, see gpu_validate_call.