chromadb
Version:
A JavaScript interface for chroma
96 lines (81 loc) • 3.05 kB
text/typescript
import type { SearchResponse } from "../../api";
import type { Metadata } from "../../types";
import { deserializeMetadatas } from "../../utils";
export interface SearchResultRow {
id: string;
document?: string | null;
embedding?: number[] | null;
metadata?: Metadata | null;
score?: number | null;
}
const normalizePayloadArray = <T>(
payload: Array<T[] | null> | null | undefined,
count: number,
): Array<T[] | null> => {
if (!payload) {
return Array(count).fill(null);
}
if (payload.length === count) {
return payload.map((item) => (item ? item.slice() : null));
}
const result: Array<T[] | null> = payload.map((item) => (item ? item.slice() : null));
while (result.length < count) {
result.push(null);
}
return result;
};
export class SearchResult {
public readonly ids: string[][];
public readonly documents: Array<Array<string | null> | null>;
public readonly embeddings: Array<Array<Array<number> | null> | null>;
public readonly metadatas: Array<Array<Metadata | null> | null>;
public readonly scores: Array<Array<number | null> | null>;
public readonly select: SearchResponse["select"];
constructor(response: SearchResponse) {
this.ids = response.ids;
const payloadCount = this.ids.length;
this.documents = normalizePayloadArray(response.documents, payloadCount);
this.embeddings = normalizePayloadArray(response.embeddings, payloadCount);
const rawMetadatas = normalizePayloadArray(response.metadatas, payloadCount);
this.metadatas = rawMetadatas.map((payload) => {
if (!payload) {
return null;
}
return deserializeMetadatas(payload) ?? [];
});
this.scores = normalizePayloadArray(response.scores, payloadCount);
this.select = response.select ?? [];
}
public rows(): SearchResultRow[][] {
const results: SearchResultRow[][] = [];
for (let payloadIndex = 0; payloadIndex < this.ids.length; payloadIndex += 1) {
const ids = this.ids[payloadIndex];
const docPayload = this.documents[payloadIndex] ?? [];
const embedPayload = this.embeddings[payloadIndex] ?? [];
const metaPayload = this.metadatas[payloadIndex] ?? [];
const scorePayload = this.scores[payloadIndex] ?? [];
const rows: SearchResultRow[] = ids.map((id, rowIndex) => {
const row: SearchResultRow = { id };
const document = docPayload[rowIndex];
if (document !== undefined && document !== null) {
row.document = document;
}
const embedding = embedPayload[rowIndex];
if (embedding !== undefined && embedding !== null) {
row.embedding = embedding;
}
const metadata = metaPayload[rowIndex];
if (metadata !== undefined && metadata !== null) {
row.metadata = metadata;
}
const score = scorePayload[rowIndex];
if (score !== undefined && score !== null) {
row.score = score;
}
return row;
});
results.push(rows);
}
return results;
}
}