fix(ts-oss/baidu): convert L2 distance to similarity score in search() (#6485)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
This commit is contained in:
co-authored by
kartik-mem0
parent
dd5f7e39a8
commit
f590c9596a
@@ -453,7 +453,13 @@ export class BaiduDB implements VectorStore {
|
|||||||
return (response.rows ?? []).map((result) => ({
|
return (response.rows ?? []).map((result) => ({
|
||||||
id: String(result.row.id),
|
id: String(result.row.id),
|
||||||
payload: resultPayload(result.row),
|
payload: resultPayload(result.row),
|
||||||
score: result.score,
|
// L2 is a distance (lower = closer); the VectorStore contract wants higher = better.
|
||||||
|
score:
|
||||||
|
this.metricType === "L2"
|
||||||
|
? result.score != null
|
||||||
|
? 1 / (1 + result.score)
|
||||||
|
: undefined
|
||||||
|
: result.score,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -431,9 +431,12 @@ describe("BaiduDB reads", () => {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const results = await makeStore(client).search([1, 2, 3], 5, {
|
// Non-L2 metrics already return a higher-is-better score and pass through untouched.
|
||||||
userId: "alice",
|
const results = await makeStore(client, { metricType: "COSINE" }).search(
|
||||||
});
|
[1, 2, 3],
|
||||||
|
5,
|
||||||
|
{ userId: "alice" },
|
||||||
|
);
|
||||||
expect(results).toEqual([{ id: "m1", payload: { data: "x" }, score: 0.8 }]);
|
expect(results).toEqual([{ id: "m1", payload: { data: "x" }, score: 0.8 }]);
|
||||||
|
|
||||||
const { request } = client.vectorSearch.mock.calls[0][0];
|
const { request } = client.vectorSearch.mock.calls[0][0];
|
||||||
@@ -445,6 +448,35 @@ describe("BaiduDB reads", () => {
|
|||||||
expect(request.config.params).toEqual({ ef: 200 });
|
expect(request.config.params).toEqual({ ef: 200 });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("converts an L2 distance into a similarity score (higher = better)", async () => {
|
||||||
|
// Mirrors the Python provider (#6435): 1 / (1 + distance), so closer scores higher.
|
||||||
|
const client = fakeClient();
|
||||||
|
client.vectorSearch.mockResolvedValue({
|
||||||
|
...OK,
|
||||||
|
rows: [
|
||||||
|
{ row: { id: "near", metadata: {} }, score: 0.5 },
|
||||||
|
{ row: { id: "far", metadata: {} }, score: 2.0 },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const results = await makeStore(client).search([1, 2, 3], 2);
|
||||||
|
|
||||||
|
expect(results[0].score).toBeCloseTo(1 / 1.5, 10);
|
||||||
|
expect(results[1].score).toBeCloseTo(1 / 3.0, 10);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("leaves an unscored L2 row's score undefined instead of treating it as the closest match", async () => {
|
||||||
|
const client = fakeClient();
|
||||||
|
client.vectorSearch.mockResolvedValue({
|
||||||
|
...OK,
|
||||||
|
rows: [{ row: { id: "unscored", metadata: {} } }],
|
||||||
|
});
|
||||||
|
|
||||||
|
const results = await makeStore(client).search([1, 2, 3], 1);
|
||||||
|
|
||||||
|
expect(results[0].score).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
it("omits the filter when no filters are supplied", async () => {
|
it("omits the filter when no filters are supplied", async () => {
|
||||||
const client = fakeClient();
|
const client = fakeClient();
|
||||||
client.vectorSearch.mockResolvedValue({ ...OK, rows: [] });
|
client.vectorSearch.mockResolvedValue({ ...OK, rows: [] });
|
||||||
|
|||||||
Reference in New Issue
Block a user