@@ -27,71 +27,55 @@ Get the *API endpoint* and your *application token* for your Astra DB instance @
27
27
### Collections
28
28
29
29
``` typescript
30
- import { DataAPIClient , VectorDoc , UUID , ObjectId } from ' @datastax/astra-db-ts' ;
31
-
32
- // Schema for the collections (VectorDoc adds the $vector field)
33
- interface Idea extends VectorDoc {
34
- idea: string ,
35
- }
30
+ import { DataAPIClient , ObjectId , vector , VectorDoc , oid } from ' @datastax/astra-db-ts' ;
36
31
37
32
// Connect to the db
38
- const client = new DataAPIClient (' *TOKEN*' );
39
- const db = client .db (' *ENDPOINT*' , { namespace: ' *NAMESPACE*' });
33
+ const client = new DataAPIClient ({ logging: ' all' });
34
+ const db = client .db (process .env .CLIENT_DB_URL ! , { token: process .env .CLIENT_DB_TOKEN ! });
35
+
36
+ // The `VectorDoc` interface adds `$vector?: DataAPIVector` as a field to the collection type
37
+ interface Dream extends VectorDoc {
38
+ _id: ObjectId , // Uses an `astra-db-ts` provided type here (NOT the `bson` version)
39
+ summary: string ,
40
+ tags? : string [], // No sets/maps available without creating custom ser/des rules
41
+ }
40
42
41
43
(async () => {
42
- // Creates collections, or gets it if it already exists with same options
43
- const collection = await db .createCollection <Idea >(' vector_5_collection' , {
44
- vector: {
45
- dimension: 5 ,
46
- metric: ' cosine' ,
47
- },
48
- checkExists: false ,
44
+ // Create the table using our helper function.
45
+ // The _id should be an `ObjectId` type, as specified by `defaultId.type`
46
+ const collection = await db .createCollection <Dream >(' dreams' , {
47
+ defaultId: { type: ' objectId' },
49
48
});
50
49
51
- // Insert many ideas into the collections
52
- const ideas = [
53
- {
54
- idea: ' An AI quilt to help you sleep forever' ,
55
- $vector: [0.1 , 0.15 , 0.3 , 0.12 , 0.05 ],
56
- },
57
- {
58
- _id: new UUID (' e7f1f3a0-7e3d-11eb-9439-0242ac130002' ),
59
- idea: ' Vision Vector Frame—A deep learning display that controls your mood' ,
60
- $vector: [0.1 , 0.05 , 0.08 , 0.3 , 0.6 ],
61
- },
62
- {
63
- idea: ' A smartwatch that tells you what to eat based on your mood' ,
64
- $vector: [0.2 , 0.3 , 0.1 , 0.4 , 0.15 ],
65
- },
66
- ];
67
- await collection .insertMany (ideas );
68
-
69
- // Insert a specific idea into the collections
70
- const sneakersIdea = {
71
- _id: new ObjectId (' 507f191e810c19729de860ea' ),
72
- idea: ' ChatGPT-integrated sneakers that talk to you' ,
73
- $vector: [0.45 , 0.09 , 0.01 , 0.2 , 0.11 ],
74
- }
75
- await collection .insertOne (sneakersIdea );
50
+ // Batch-insert some rows into the table
51
+ // _id can be optionally provided, or be auto-generated @ the server side
52
+ await collection .insertMany ([{
53
+ summary: ' A dinner on the Moon' ,
54
+ $vector: vector ([0.2 , - 0.3 , - 0.5 ]), // Shorthand for `new DataAPIVector([0.2, -0.3, -0.5])`
55
+ }, {
56
+ summary: ' Riding the waves' ,
57
+ $vector: vector ([0 , 0.2 , 1 ]),
58
+ tags: [' sport' ],
59
+ }, {
60
+ _id: oid (' 674f0f5c1c162131319fa09e' ), // Shorthand for `new ObjectId('674f0f5c1c162131319fa09e')`
61
+ summary: ' Meeting Beethoven at the dentist' ,
62
+ $vector: vector ([0.2 , 0.6 , 0 ]),
63
+ }]);
76
64
77
- // Actually, let's change that idea
78
- await collection .updateOne (
79
- { _id: sneakersIdea ._id },
80
- { $set: { idea: ' Gemini-integrated sneakers that talk to you' } },
81
- );
65
+ // Hm, changed my mind
66
+ await collection .updateOne ({ id: 103 }, { $set: { summary: ' Surfers\' paradise' } });
82
67
83
- // Get similar results as desired
84
- const cursor = collection .find ({}, {
85
- vector: [0.1 , 0.15 , 0.3 , 0.12 , 0.05 ],
86
- includeSimilarity: true ,
87
- limit: 2 ,
88
- });
68
+ // Let's see what we've got
69
+ const cursor = collection .find ({})
70
+ .sort ({ vector: vector ([0 , 0.2 , 0.4 ]) }) // Performing a vector search
71
+ .includeSimilarity (true ) // The found doc is inferred to have `$similarity` as a property now
72
+ .limit (2 );
89
73
90
- for await ( const doc of cursor ) {
91
- // Prints the following:
92
- // - An AI quilt to help you sleep forever: 1
93
- // - A smartwatch that tells you what to eat based on your mood: 0.85490346
94
- console .log (` ${doc . idea }: ${doc .$similarity } ` );
74
+ // This would print:
75
+ // - Surfers' paradise: 0.98238194
76
+ // - Friendly aliens in town: 0.91873914
77
+ for await ( const result of cursor ) {
78
+ console .log (` ${result . summary }: ${result .$similarity } ` );
95
79
}
96
80
97
81
// Cleanup (if desired)
@@ -102,57 +86,59 @@ const db = client.db('*ENDPOINT*', { namespace: '*NAMESPACE*' });
102
86
### Tables
103
87
104
88
``` typescript
105
- import { CreateTableDefinition , DataAPIClient , InferTableSchema , vector } from ' @datastax/astra-db-ts' ;
89
+ import { DataAPIClient , InferTableSchema , vector } from ' @datastax/astra-db-ts' ;
106
90
107
91
// Connect to the db
108
- const client = new DataAPIClient ();
109
- const db = client .db (' https://178cf75b-ec19-4d13-9ca7-b6dcfa613157-us-west-2.apps.astra-dev.datastax.com' , { token: ' AstraCS:EFZEBUXuMzwyFntFYcroNsWQ:e473c9b244253e3c873346cc8584d4767789d93e54c6c5453c996fbd5ab4605d' });
110
-
111
- // Example table schema using bespoke Data API table definition syntax
112
- const TableDefinition = <const >{
113
- columns: {
114
- id: ' int' ,
115
- summary: ' text' ,
116
- tags: { type: ' set' , valueType: ' text' },
117
- vector: { type: ' vector' , dimension: 3 },
118
- },
119
- primaryKey: {
120
- partitionBy: [' id' ],
92
+ const client = new DataAPIClient ({ logging: ' all' });
93
+ const db = client .db (process .env .CLIENT_DB_URL ! , { token: process .env .CLIENT_DB_TOKEN ! });
94
+
95
+ // Create a table through the Data API if it does not yet exist.
96
+ // Returns the created table through a function so we can use the inferred type of the table ourselves
97
+ // (instead of having to manually define it)
98
+ const mkDreamsTable = async () => await db .createTable (' dreams' , {
99
+ definition: {
100
+ columns: {
101
+ id: ' int' , // Shorthand notation for { type: 'int' }
102
+ summary: ' text' ,
103
+ tags: { type: ' set' , valueType: ' text' }, // Collection types require additional type information
104
+ vector: { type: ' vector' , dimension: 3 }, // Auto-embedding-generation can be enabled through a `service` block
105
+ },
106
+ primaryKey: ' id' , // Shorthand for { partitionBy: ['id'] }
121
107
},
122
- } satisfies CreateTableDefinition ;
108
+ ifNotExists: true , // If any table with the same name exists, do nothing
109
+ }); // (note that this does not check if the tables are the same)
123
110
124
111
// Infer the TS-equivalent type from the table definition (like zod or arktype). Equivalent to:
125
112
//
126
- // interface TableSchema extends Row<'id'> { // Types 'id' as a primary key for insertion command return types
127
- // summary?: string | null; // Not a primary key, so it's optional and may return as null when found
128
- // tags?: Set<string>; // Sets/maps/lists are optional to insert, but will actually be returned as empty collections instead of null
129
- // vector?: DataAPIVector | null; // Vectors, however, may be null.
113
+ // interface TableSchema extends Row<'id'> {
114
+ // id: number, -- A primary key component, so it's required
115
+ // summary?: string | null, -- Not a primary key, so it's optional and may return as null when found
116
+ // tags?: Set<string>, -- Sets/maps/lists are optional to insert, but will actually be returned as empty collections instead of null
117
+ // vector?: DataAPIVector | null, -- Vectors, however, may be null.
130
118
// }
131
- type TableSchema = InferTableSchema <typeof TableDefinition >;
119
+ type Dream = InferTableSchema <typeof mkDreamsTable >;
132
120
133
121
(async () => {
134
- // Create the table if it doesn't alredy exist
135
- const table = await db .createTable (' dreams' , {
136
- definition: TableDefinition ,
137
- ifNotExists: true ,
138
- });
122
+ // Create the table using our helper function.
123
+ // Table will be typed as `Table<Dream, { id: number }>`, where the former is the schema, and the latter is the primary key
124
+ const table = await mkDreamsTable ();
139
125
140
126
// Enables vector search on the table (on the 'vector' column)
141
127
await table .createVectorIndex (' dreams_vector_idx' , ' vector' , {
142
128
options: { metric: ' cosine' },
143
129
ifNotExists: true ,
144
130
});
145
131
146
- // Insert some rows into the table
147
- const rows: TableSchema [] = [{
132
+ // Batch-insert some rows into the table
133
+ const rows: Dream [] = [{
148
134
id: 102 ,
149
135
summary: ' A dinner on the Moon' ,
150
136
vector: vector ([0.2 , - 0.3 , - 0.5 ]), // Shorthand for `new DataAPIVector([0.2, -0.3, -0.5])`
151
137
}, {
152
138
id: 103 ,
153
139
summary: ' Riding the waves' ,
154
- tags: new Set ([' sport' ]),
155
140
vector: vector ([0 , 0.2 , 1 ]),
141
+ tags: new Set ([' sport' ]), // Collection types use native JS collections
156
142
}, {
157
143
id: 37 ,
158
144
summary: ' Meeting Beethoven at the dentist' ,
@@ -164,11 +150,10 @@ type TableSchema = InferTableSchema<typeof TableDefinition>;
164
150
await table .updateOne ({ id: 103 }, { $set: { summary: ' Surfers\' paradise' } });
165
151
166
152
// Let's see what we've got
167
- const cursor = table .find ({}, {
168
- sort: { vector: vector ([0 , 0.2 , 0.4 ]) },
169
- includeSimilarity: true ,
170
- limit: 2 ,
171
- });
153
+ const cursor = table .find ({})
154
+ .sort ({ vector: vector ([0 , 0.2 , 0.4 ]) }) // Performing a vector search
155
+ .includeSimilarity (true ) // The found doc is inferred to have `$similarity` as a property now
156
+ .limit (2 );
172
157
173
158
// This would print:
174
159
// - Surfers' paradise: 0.98238194
0 commit comments