/
vector_search.ts
123 lines (114 loc) · 3.28 KB
/
vector_search.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import { Id, Value } from "../values/value.js";
import {
DocumentByInfo,
FieldTypeFromFieldPath,
GenericDataModel,
GenericDocument,
GenericTableInfo,
GenericVectorIndexConfig,
NamedTableInfo,
NamedVectorIndex,
TableNamesInDataModel,
VectorIndexNames,
} from "./data_model.js";
/**
* An object with parameters for performing a vector search against a vector index.
* @public
*/
export interface VectorSearchQuery<
TableInfo extends GenericTableInfo,
IndexName extends VectorIndexNames<TableInfo>,
> {
/**
* The query vector.
*
* This must have the same length as the `dimensions` of the index.
* This vector search will return the IDs of the documents most similar to
* this vector.
*/
vector: number[];
/**
* The number of results to return. If specified, must be between 1 and 256
* inclusive.
*
* @default 10
*/
limit?: number;
/**
* Optional filter expression made up of `q.or` and `q.eq` operating
* over the filter fields of the index.
*
* e.g. `filter: q => q.or(q.eq("genre", "comedy"), q.eq("genre", "drama"))`
*
* @param q
* @returns
*/
filter?: (
q: VectorFilterBuilder<
DocumentByInfo<TableInfo>,
NamedVectorIndex<TableInfo, IndexName>
>,
) => FilterExpression<boolean>;
}
export type VectorSearch<
DataModel extends GenericDataModel,
TableName extends TableNamesInDataModel<DataModel>,
IndexName extends VectorIndexNames<NamedTableInfo<DataModel, TableName>>,
> = (
tableName: TableName,
indexName: IndexName,
query: VectorSearchQuery<NamedTableInfo<DataModel, TableName>, IndexName>,
) => Promise<Array<{ _id: Id<TableName>; _score: number }>>;
/**
* Expressions are evaluated to produce a {@link values.Value} in the course of executing a query.
*
* To construct an expression, use the {@link VectorFilterBuilder} provided within
* {@link VectorSearchQuery}.
*
* @typeParam T - The type that this expression evaluates to.
* @public
*/
export abstract class FilterExpression<T extends Value | undefined> {
// Property for nominal type support.
private _isExpression: undefined;
// Property to distinguish expressions by the type they resolve to.
private _value!: T;
/**
* @internal
*/
constructor() {
// only defining the constructor so we can mark it as internal and keep
// it out of the docs.
}
}
/**
* An interface for defining filters for vector searches.
*
* This has a similar interface to {@link FilterBuilder}, which is used in
* database queries, but supports only the methods that can be efficiently
* done in a vector search.
*
* @public
*/
export interface VectorFilterBuilder<
Document extends GenericDocument,
VectorIndexConfig extends GenericVectorIndexConfig,
> {
// Comparisons /////////////////////////////////////////////////////////////
/**
* Is the field at `fieldName` equal to `value`
*
* @public
* */
eq<FieldName extends VectorIndexConfig["filterFields"]>(
fieldName: FieldName,
value: FieldTypeFromFieldPath<Document, FieldName>,
): FilterExpression<boolean>;
// Logic ///////////////////////////////////////////////////////////////////
/**
* `exprs[0] || exprs[1] || ... || exprs[n]`
*
* @public
*/
or(...exprs: Array<FilterExpression<boolean>>): FilterExpression<boolean>;
}