RI-8159: [BE] vector set similarity#5867
Conversation
🛡️ Jit Security Scan Results✅ No security findings were detected in this PR
Security scan by Jit
|
Code Coverage - Integration Tests
|
Code Coverage - Backend unit tests
Test suite run success3413 tests passing in 306 suites. Report generated by 🧪jest coverage report action from da7c971 |
| count: faker.number.int({ min: 1, max: 100 }), | ||
| })); | ||
|
|
||
| export const searchVectorSetByValuesDtoFactory = |
There was a problem hiding this comment.
I don't think we need to define 3 separate factories here - it's really a single data type with variations on its data (whether it carries vectorValues, vectorFp32, or something else).
I know it sounds a bit more complex to define a single factory and toggle which fields get prefilled internally (via transient params), but the entity itself is a single one - a vector set - and if it changes at some point, we'd only need to update one factory instead of keeping all the variants in sync.
Here's a quick sketch of what I mean:
interface VectorSetTransientParams {
variant: VectorVariant;
}
export const vectorSetFactory = Factory.define<VectorSet, VectorSetTransientParams>(
({ transientParams }) => {
const { variant = 'none' } = transientParams;
return {
keyName: Buffer.from(`vset:${faker.string.alphanumeric(6)}`),
elementName: Buffer.from(faker.string.alphanumeric(8)),
vectorValues: variant === 'values' ? [/* fill defaults */] : undefined,
vectorFp32: variant === 'fp32' ? Buffer.from(/* ... */) : undefined,
count: faker.number.int({ min: 1, max: 100 }),
};
},
);
// Usage:
vectorSetFactory.build({}, { transient: { variant: 'values' } }); // values variant
vectorSetFactory.build({}, { transient: { variant: 'fp32' } }); // fp32 variantAnd if a specific test needs custom values, regular params still take precedence over the transient defaults:
vectorSetFactory.build(
{ vectorFp32: Buffer.from([/* ... */]) },
{ transient: { variant: 'fp32' } },
);Docs for reference:
- Fishery README — Transient params section: https://github.com/thoughtbot/fishery#transient-params
Happy to pair on it if it'd be easier - totally fine to keep things as-is too if you'd rather not expand scope on this PR!
There was a problem hiding this comment.
thanks! not at all, seems reasonable and it is in scope anyway
88faba9 to
fc43cca
Compare
| | `count` | number | Maximum number of results (omitted from preview when undefined) | | ||
| | `filter` | string | Optional filter expression evaluated against element attributes | | ||
|
|
||
| At most one of `elementName`, `vectorValues`, `vectorFp32` may be present. Supplying more than one returns `400`. |
There was a problem hiding this comment.
Note: As we discussed offline, you can add examples for the various ways of using this API endpoint, but it can happen in a separate PR :)
There was a problem hiding this comment.
good note. I'll tackle this in a separate PR
| description: | ||
| 'Build a human-readable preview of the VSIM command that the similarity-search endpoint would execute for the supplied DTO. ' + | ||
| 'Reuses the same internal command builder as the search endpoint so the preview cannot drift from what is actually executed. ' + | ||
| 'Returns an empty `preview` string when no query payload (`elementName` / `vectorValues` / `vectorFp32`) is supplied.', |
There was a problem hiding this comment.
nit: Why don't we enforce the same validation rules as for the other endpoints - to have at least one correct param passed, since the other validation (when you pass more than a single param) is already in place?
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 4d983b1. Configure here.
4d983b1 to
da7c971
Compare

What
Add two backend endpoints for the vector-set similarity-search feature:
POST /vector-set/similarity-search— runsVSIMagainst the supplied key and returns the matches (name+score+ optionalattributes).POST /vector-set/similarity-search/preview— returns the sameVSIMinvocation as a CLI-friendly string so the FE can show users the command they're about to run.Both endpoints accept a single
SimilaritySearchDtoand pick the query mode (ELE/VALUES/FP32) at runtime — exactly one ofelementName,vectorValues, orvectorFp32must be supplied.WITHSCORESandWITHATTRIBSare always appended so the response shape is stable;COUNT/FILTERare forwarded only when present.The command builder, preview formatter, reply parser, and shared
VsimTokenWriterstrategy live invector-set.utils.tsso the executable command and its preview can't drift on clause order or rendering.VSIMis also registered as a built-in ioredis command.Testing
Note
Medium Risk
Adds new API endpoints that execute Redis
VSIMand parse its flat reply format, so correctness depends on command construction and reply parsing across RESP2/RESP3 types. Risk is mitigated by extensive unit tests but touches runtime Redis command execution.Overview
Adds vector-set similarity search support via
POST /vector-set/similarity-search(executesVSIMwith mandatoryWITHSCORES WITHATTRIBSand optionalCOUNT/FILTER) andPOST /vector-set/similarity-search/preview(returns a CLI-safe command string preview).Introduces new DTOs/responses for search results and preview, registers
VSIMas a built-in ioredis command, and centralizes VSIM command building/preview formatting/reply parsing invector-set.utils.tswith tests covering query-mode validation (ELE/VALUES/FP32), quoting/escaping, and score/attributes decoding.Reviewed by Cursor Bugbot for commit da7c971. Bugbot is set up for automated code reviews on this repo. Configure here.