chub-dev 0.1.0 → 0.2.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/anthropic/docs/sdk/javascript/DOC.md +499 -0
- package/dist/anthropic/docs/sdk/python/DOC.md +382 -0
- package/dist/openai/docs/chat/javascript/DOC.md +350 -0
- package/dist/openai/docs/chat/python/DOC.md +526 -0
- package/dist/pinecone/docs/sdk/javascript/DOC.md +984 -0
- package/dist/pinecone/docs/sdk/python/DOC.md +1395 -0
- package/dist/registry.json +276 -0
- package/dist/resend/docs/sdk/DOC.md +1271 -0
- package/dist/stripe/docs/api/DOC.md +1726 -0
- package/dist/supabase/docs/sdk/DOC.md +1606 -0
- package/dist/twilio/docs/sdk/python/DOC.md +469 -0
- package/dist/twilio/docs/sdk/typescript/DOC.md +946 -0
- package/package.json +16 -5
- package/src/commands/build.js +3 -1
- package/src/commands/feedback.js +150 -0
- package/src/commands/get.js +11 -0
- package/src/commands/search.js +7 -0
- package/src/index.js +12 -2
- package/src/lib/analytics.js +90 -0
- package/src/lib/cache.js +55 -6
- package/src/lib/config.js +6 -1
- package/src/lib/identity.js +99 -0
- package/src/lib/telemetry.js +86 -0
|
@@ -0,0 +1,984 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sdk
|
|
3
|
+
description: "Vector database for AI applications with semantic search, hybrid search, reranking, and integrated embeddings"
|
|
4
|
+
metadata:
|
|
5
|
+
languages: "javascript"
|
|
6
|
+
versions: "6.1.2"
|
|
7
|
+
updated-on: "2025-10-26"
|
|
8
|
+
source: maintainer
|
|
9
|
+
tags: "pinecone,sdk,vector-db,ai,search"
|
|
10
|
+
---
|
|
11
|
+
# Pinecone JavaScript/TypeScript SDK Coding Guidelines
|
|
12
|
+
|
|
13
|
+
You are a Pinecone vector database coding expert. Help me with writing code using the Pinecone SDK for JavaScript/TypeScript.
|
|
14
|
+
|
|
15
|
+
You can find the official SDK documentation and code samples here:
|
|
16
|
+
https://docs.pinecone.io/
|
|
17
|
+
|
|
18
|
+
## Golden Rule: Use the Correct and Current SDK
|
|
19
|
+
|
|
20
|
+
Always use the official Pinecone TypeScript SDK for all Pinecone vector database interactions. Do not use legacy libraries or unofficial packages.
|
|
21
|
+
|
|
22
|
+
- **Library Name:** Pinecone TypeScript SDK
|
|
23
|
+
- **NPM Package:** `@pinecone-database/pinecone`
|
|
24
|
+
- **Legacy Libraries**: `pinecone-client` and other unofficial packages are not recommended
|
|
25
|
+
|
|
26
|
+
**Installation:**
|
|
27
|
+
|
|
28
|
+
- **Correct:** `npm install @pinecone-database/pinecone`
|
|
29
|
+
|
|
30
|
+
**APIs and Usage:**
|
|
31
|
+
|
|
32
|
+
- **Correct:** `import { Pinecone } from '@pinecone-database/pinecone'`
|
|
33
|
+
- **Correct:** `const pc = new Pinecone({})`
|
|
34
|
+
- **Correct:** `await pc.createIndex(...)`
|
|
35
|
+
- **Correct:** `pc.index('index-name')`
|
|
36
|
+
- **Incorrect:** `PineconeClient`
|
|
37
|
+
- **Incorrect:** Legacy initialization patterns
|
|
38
|
+
|
|
39
|
+
**Important Security Note:**
|
|
40
|
+
|
|
41
|
+
The Pinecone TypeScript SDK is intended for server-side use only. Using the SDK within a browser context can expose your API key(s). Always use server-side code or proxy requests through a backend.
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
Install the Pinecone SDK using npm:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm install @pinecone-database/pinecone
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Requirements:**
|
|
52
|
+
- TypeScript >=4.1
|
|
53
|
+
- Node.js >=18.x
|
|
54
|
+
|
|
55
|
+
## Initialization and API Key
|
|
56
|
+
|
|
57
|
+
The SDK requires creating a `Pinecone` instance for all API calls.
|
|
58
|
+
|
|
59
|
+
### Using Environment Variables
|
|
60
|
+
|
|
61
|
+
Set your API key as an environment variable:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
export PINECONE_API_KEY="your_api_key_here"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Then initialize without arguments:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { Pinecone } from '@pinecone-database/pinecone';
|
|
71
|
+
|
|
72
|
+
const pc = new Pinecone();
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Using Configuration Object
|
|
76
|
+
|
|
77
|
+
Pass credentials directly:
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
import { Pinecone } from '@pinecone-database/pinecone';
|
|
81
|
+
|
|
82
|
+
const pc = new Pinecone({
|
|
83
|
+
apiKey: 'your_api_key_here',
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### With Custom Retry Configuration
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
import { Pinecone } from '@pinecone-database/pinecone';
|
|
91
|
+
|
|
92
|
+
const pc = new Pinecone({
|
|
93
|
+
apiKey: process.env.PINECONE_API_KEY,
|
|
94
|
+
maxRetries: 5,
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The `maxRetries` parameter (defaults to 3) applies to operations like `upsert`, `update`, and `configureIndex`.
|
|
99
|
+
|
|
100
|
+
## Creating Indexes
|
|
101
|
+
|
|
102
|
+
### Serverless Index (Basic)
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
import { Pinecone } from '@pinecone-database/pinecone';
|
|
106
|
+
|
|
107
|
+
const pc = new Pinecone();
|
|
108
|
+
|
|
109
|
+
await pc.createIndex({
|
|
110
|
+
name: 'my-index',
|
|
111
|
+
dimension: 1536,
|
|
112
|
+
metric: 'cosine',
|
|
113
|
+
spec: {
|
|
114
|
+
serverless: {
|
|
115
|
+
cloud: 'aws',
|
|
116
|
+
region: 'us-west-2',
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Serverless Index with Wait
|
|
123
|
+
|
|
124
|
+
Use `waitUntilReady` to block until the index is operational:
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
await pc.createIndex({
|
|
128
|
+
name: 'serverless-index',
|
|
129
|
+
dimension: 1536,
|
|
130
|
+
metric: 'cosine',
|
|
131
|
+
spec: {
|
|
132
|
+
serverless: {
|
|
133
|
+
cloud: 'aws',
|
|
134
|
+
region: 'us-east-1',
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
waitUntilReady: true,
|
|
138
|
+
});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Pod-Based Index
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
await pc.createIndex({
|
|
145
|
+
name: 'pod-index',
|
|
146
|
+
dimension: 1536,
|
|
147
|
+
metric: 'dotproduct',
|
|
148
|
+
spec: {
|
|
149
|
+
pod: {
|
|
150
|
+
environment: 'us-west-2',
|
|
151
|
+
podType: 'p1.x1',
|
|
152
|
+
pods: 1,
|
|
153
|
+
replicas: 1,
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Hybrid Search Index (Sparse-Dense)
|
|
160
|
+
|
|
161
|
+
For hybrid search supporting both dense and sparse vectors, use `dotproduct` metric:
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
await pc.createIndex({
|
|
165
|
+
name: 'hybrid-index',
|
|
166
|
+
dimension: 1024,
|
|
167
|
+
metric: 'dotproduct',
|
|
168
|
+
spec: {
|
|
169
|
+
serverless: {
|
|
170
|
+
cloud: 'aws',
|
|
171
|
+
region: 'us-east-1',
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**Note:** The `dotproduct` metric is the only metric that supports sparse-dense hybrid search.
|
|
178
|
+
|
|
179
|
+
## Index Management
|
|
180
|
+
|
|
181
|
+
### Describe Index
|
|
182
|
+
|
|
183
|
+
Get index details including status, dimension, and host:
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
const indexStats = await pc.describeIndex('my-index');
|
|
187
|
+
console.log(indexStats);
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### List All Indexes
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
const indexList = await pc.listIndexes();
|
|
194
|
+
console.log(indexList.indexes);
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Delete Index
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
await pc.deleteIndex('my-index');
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Configure Index (Scale)
|
|
204
|
+
|
|
205
|
+
For pod-based indexes, adjust replicas and pod type:
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
await pc.configureIndex('pod-index', {
|
|
209
|
+
spec: {
|
|
210
|
+
pod: {
|
|
211
|
+
replicas: 2,
|
|
212
|
+
podType: 'p1.x2',
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Connecting to an Index
|
|
219
|
+
|
|
220
|
+
### Basic Connection
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
import { Pinecone } from '@pinecone-database/pinecone';
|
|
224
|
+
|
|
225
|
+
const pc = new Pinecone();
|
|
226
|
+
const index = pc.index('my-index');
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Connection with Namespace
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
const pc = new Pinecone();
|
|
233
|
+
const index = pc.index('my-index').namespace('my-namespace');
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Connection with Host (Faster)
|
|
237
|
+
|
|
238
|
+
If you know the index host, connect directly:
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
const pc = new Pinecone();
|
|
242
|
+
const index = pc.index('my-index', 'https://my-index-abc123.svc.pinecone.io');
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Upserting Vectors
|
|
246
|
+
|
|
247
|
+
### Dense Vectors (Basic)
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
const pc = new Pinecone();
|
|
251
|
+
const index = pc.index('my-index');
|
|
252
|
+
|
|
253
|
+
await index.upsert([
|
|
254
|
+
{
|
|
255
|
+
id: 'vec1',
|
|
256
|
+
values: [0.1, 0.2, 0.3, 0.4, 0.5],
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
id: 'vec2',
|
|
260
|
+
values: [0.2, 0.3, 0.4, 0.5, 0.6],
|
|
261
|
+
},
|
|
262
|
+
]);
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Dense Vectors with Metadata
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
await index.upsert([
|
|
269
|
+
{
|
|
270
|
+
id: 'vec1',
|
|
271
|
+
values: [0.1, 0.2, 0.3, 0.4, 0.5],
|
|
272
|
+
metadata: {
|
|
273
|
+
genre: 'comedy',
|
|
274
|
+
year: 2020,
|
|
275
|
+
title: 'Movie Title',
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
id: 'vec2',
|
|
280
|
+
values: [0.2, 0.3, 0.4, 0.5, 0.6],
|
|
281
|
+
metadata: {
|
|
282
|
+
genre: 'action',
|
|
283
|
+
year: 2021,
|
|
284
|
+
title: 'Another Movie',
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
]);
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Namespaced Upsert
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
const pc = new Pinecone();
|
|
294
|
+
const ns = pc.index('my-index').namespace('example-namespace');
|
|
295
|
+
|
|
296
|
+
await ns.upsert([
|
|
297
|
+
{
|
|
298
|
+
id: 'vec1',
|
|
299
|
+
values: [0.1, 0.2, 0.3],
|
|
300
|
+
metadata: { category: 'A' },
|
|
301
|
+
},
|
|
302
|
+
]);
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Batch Upsert (Large Datasets)
|
|
306
|
+
|
|
307
|
+
For upserting many vectors, batch them in groups of up to 1,000 records (max 2 MB per batch):
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
const batchSize = 1000;
|
|
311
|
+
const vectors = []; // Your vector array
|
|
312
|
+
|
|
313
|
+
for (let i = 0; i < vectors.length; i += batchSize) {
|
|
314
|
+
const batch = vectors.slice(i, i + batchSize);
|
|
315
|
+
await index.upsert(batch);
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Sparse-Dense Vectors (Hybrid Search)
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
await index.upsert([
|
|
323
|
+
{
|
|
324
|
+
id: 'vec1',
|
|
325
|
+
values: [0.1, 0.2, 0.3], // Dense vector
|
|
326
|
+
sparseValues: {
|
|
327
|
+
indices: [10, 45, 16],
|
|
328
|
+
values: [0.5, 0.5, 0.2],
|
|
329
|
+
},
|
|
330
|
+
metadata: { text: 'original text content' },
|
|
331
|
+
},
|
|
332
|
+
]);
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## Querying Vectors
|
|
336
|
+
|
|
337
|
+
### Basic Query (Dense)
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
const pc = new Pinecone();
|
|
341
|
+
const index = pc.index('my-index');
|
|
342
|
+
|
|
343
|
+
const queryResponse = await index.query({
|
|
344
|
+
vector: [0.1, 0.2, 0.3, 0.4, 0.5],
|
|
345
|
+
topK: 10,
|
|
346
|
+
includeMetadata: true,
|
|
347
|
+
includeValues: false,
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
console.log(queryResponse.matches);
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Query with Metadata Filter
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
const queryResponse = await index.query({
|
|
357
|
+
vector: [0.1, 0.2, 0.3, 0.4, 0.5],
|
|
358
|
+
topK: 5,
|
|
359
|
+
filter: {
|
|
360
|
+
genre: { $eq: 'comedy' },
|
|
361
|
+
},
|
|
362
|
+
includeMetadata: true,
|
|
363
|
+
});
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Complex Metadata Filters
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
// Multiple conditions with $and
|
|
370
|
+
const response = await index.query({
|
|
371
|
+
vector: [0.1, 0.2, 0.3],
|
|
372
|
+
topK: 10,
|
|
373
|
+
filter: {
|
|
374
|
+
$and: [
|
|
375
|
+
{ genre: { $eq: 'comedy' } },
|
|
376
|
+
{ year: { $gte: 2020 } },
|
|
377
|
+
],
|
|
378
|
+
},
|
|
379
|
+
includeMetadata: true,
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
// Using $or operator
|
|
383
|
+
const response2 = await index.query({
|
|
384
|
+
vector: [0.1, 0.2, 0.3],
|
|
385
|
+
topK: 10,
|
|
386
|
+
filter: {
|
|
387
|
+
$or: [
|
|
388
|
+
{ genre: { $eq: 'comedy' } },
|
|
389
|
+
{ genre: { $eq: 'drama' } },
|
|
390
|
+
],
|
|
391
|
+
},
|
|
392
|
+
includeMetadata: true,
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
// Using $in for multiple values
|
|
396
|
+
const response3 = await index.query({
|
|
397
|
+
vector: [0.1, 0.2, 0.3],
|
|
398
|
+
topK: 10,
|
|
399
|
+
filter: {
|
|
400
|
+
genre: { $in: ['comedy', 'action', 'drama'] },
|
|
401
|
+
},
|
|
402
|
+
includeMetadata: true,
|
|
403
|
+
});
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Query by ID
|
|
407
|
+
|
|
408
|
+
```typescript
|
|
409
|
+
const queryResponse = await index.query({
|
|
410
|
+
id: 'vec1',
|
|
411
|
+
topK: 10,
|
|
412
|
+
includeMetadata: true,
|
|
413
|
+
});
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Namespaced Query
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
const ns = pc.index('my-index').namespace('example-namespace');
|
|
420
|
+
|
|
421
|
+
const queryResponse = await ns.query({
|
|
422
|
+
vector: [0.1, 0.2, 0.3],
|
|
423
|
+
topK: 5,
|
|
424
|
+
includeMetadata: true,
|
|
425
|
+
});
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
### Hybrid Query (Sparse-Dense)
|
|
429
|
+
|
|
430
|
+
```typescript
|
|
431
|
+
const queryResponse = await index.query({
|
|
432
|
+
vector: [0.1, 0.2, 0.3], // Dense query vector
|
|
433
|
+
sparseVector: {
|
|
434
|
+
indices: [10, 45, 16],
|
|
435
|
+
values: [0.5, 0.5, 0.2],
|
|
436
|
+
},
|
|
437
|
+
topK: 10,
|
|
438
|
+
includeMetadata: true,
|
|
439
|
+
});
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
## Fetching Vectors
|
|
443
|
+
|
|
444
|
+
### Fetch by IDs
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
const pc = new Pinecone();
|
|
448
|
+
const index = pc.index('my-index');
|
|
449
|
+
|
|
450
|
+
const fetchResponse = await index.fetch(['vec1', 'vec2', 'vec3']);
|
|
451
|
+
console.log(fetchResponse.records);
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### Fetch from Namespace
|
|
455
|
+
|
|
456
|
+
```typescript
|
|
457
|
+
const ns = pc.index('my-index').namespace('example-namespace');
|
|
458
|
+
const fetchResponse = await ns.fetch(['vec1', 'vec2']);
|
|
459
|
+
console.log(fetchResponse.records);
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
## Updating Vectors
|
|
463
|
+
|
|
464
|
+
### Update Values
|
|
465
|
+
|
|
466
|
+
```typescript
|
|
467
|
+
const pc = new Pinecone();
|
|
468
|
+
const index = pc.index('my-index');
|
|
469
|
+
|
|
470
|
+
await index.update({
|
|
471
|
+
id: 'vec1',
|
|
472
|
+
values: [0.9, 0.8, 0.7, 0.6, 0.5],
|
|
473
|
+
});
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### Update Metadata
|
|
477
|
+
|
|
478
|
+
```typescript
|
|
479
|
+
await index.update({
|
|
480
|
+
id: 'vec1',
|
|
481
|
+
metadata: {
|
|
482
|
+
genre: 'documentary',
|
|
483
|
+
year: 2023,
|
|
484
|
+
},
|
|
485
|
+
});
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
### Update with Namespace
|
|
489
|
+
|
|
490
|
+
```typescript
|
|
491
|
+
const ns = pc.index('my-index').namespace('example-namespace');
|
|
492
|
+
|
|
493
|
+
await ns.update({
|
|
494
|
+
id: 'vec1',
|
|
495
|
+
values: [0.1, 0.2, 0.3],
|
|
496
|
+
metadata: { updated: true },
|
|
497
|
+
});
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
## Deleting Vectors
|
|
501
|
+
|
|
502
|
+
### Delete by IDs
|
|
503
|
+
|
|
504
|
+
```typescript
|
|
505
|
+
const pc = new Pinecone();
|
|
506
|
+
const index = pc.index('my-index');
|
|
507
|
+
|
|
508
|
+
await index.deleteOne('vec1');
|
|
509
|
+
|
|
510
|
+
// Delete multiple
|
|
511
|
+
await index.deleteMany(['vec1', 'vec2', 'vec3']);
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
### Delete with Metadata Filter
|
|
515
|
+
|
|
516
|
+
```typescript
|
|
517
|
+
await index.deleteMany({
|
|
518
|
+
filter: {
|
|
519
|
+
genre: { $eq: 'comedy' },
|
|
520
|
+
},
|
|
521
|
+
});
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
### Delete All in Namespace
|
|
525
|
+
|
|
526
|
+
```typescript
|
|
527
|
+
const ns = pc.index('my-index').namespace('example-namespace');
|
|
528
|
+
await ns.deleteAll();
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
**Warning:** Deleting all records from a namespace will also delete the namespace itself. This operation is irreversible.
|
|
532
|
+
|
|
533
|
+
### Delete from Specific Namespace
|
|
534
|
+
|
|
535
|
+
```typescript
|
|
536
|
+
const index = pc.index('my-index');
|
|
537
|
+
|
|
538
|
+
await index.namespace('example-namespace').deleteMany(['vec1', 'vec2']);
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
## Index Statistics
|
|
542
|
+
|
|
543
|
+
### Get Index Stats
|
|
544
|
+
|
|
545
|
+
```typescript
|
|
546
|
+
const pc = new Pinecone();
|
|
547
|
+
const index = pc.index('my-index');
|
|
548
|
+
|
|
549
|
+
const stats = await index.describeIndexStats();
|
|
550
|
+
console.log(stats);
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
Returns information including:
|
|
554
|
+
- Total vector count
|
|
555
|
+
- Dimension
|
|
556
|
+
- Index fullness
|
|
557
|
+
- Namespaces with vector counts
|
|
558
|
+
|
|
559
|
+
### Get Stats with Filter
|
|
560
|
+
|
|
561
|
+
```typescript
|
|
562
|
+
const stats = await index.describeIndexStats({
|
|
563
|
+
filter: {
|
|
564
|
+
genre: { $eq: 'comedy' },
|
|
565
|
+
},
|
|
566
|
+
});
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
## Integrated Inference (Embeddings)
|
|
570
|
+
|
|
571
|
+
Pinecone provides hosted embedding models through the Inference API.
|
|
572
|
+
|
|
573
|
+
### Generate Embeddings
|
|
574
|
+
|
|
575
|
+
```typescript
|
|
576
|
+
import { Pinecone } from '@pinecone-database/pinecone';
|
|
577
|
+
|
|
578
|
+
const pc = new Pinecone();
|
|
579
|
+
|
|
580
|
+
// Embed documents
|
|
581
|
+
const embeddings = await pc.inference.embed({
|
|
582
|
+
model: 'multilingual-e5-large',
|
|
583
|
+
inputs: [
|
|
584
|
+
{ text: 'Turkey is a classic meat to eat at American Thanksgiving.' },
|
|
585
|
+
{ text: 'Many people enjoy the beautiful mosques in Turkey.' },
|
|
586
|
+
],
|
|
587
|
+
parameters: {
|
|
588
|
+
inputType: 'passage',
|
|
589
|
+
truncate: 'END',
|
|
590
|
+
},
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
console.log(embeddings);
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
### Embed Queries
|
|
597
|
+
|
|
598
|
+
```typescript
|
|
599
|
+
const pc = new Pinecone();
|
|
600
|
+
|
|
601
|
+
const queryEmbedding = await pc.inference.embed({
|
|
602
|
+
model: 'multilingual-e5-large',
|
|
603
|
+
inputs: [{ text: 'How should I prepare my turkey?' }],
|
|
604
|
+
parameters: {
|
|
605
|
+
inputType: 'query',
|
|
606
|
+
truncate: 'END',
|
|
607
|
+
},
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
// Use the embedding for querying
|
|
611
|
+
const index = pc.index('my-index');
|
|
612
|
+
const results = await index.query({
|
|
613
|
+
vector: queryEmbedding[0].values,
|
|
614
|
+
topK: 10,
|
|
615
|
+
includeMetadata: true,
|
|
616
|
+
});
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
### Available Embedding Models
|
|
620
|
+
|
|
621
|
+
- `multilingual-e5-large`: Efficient dense embedding model trained on multilingual datasets
|
|
622
|
+
- `pinecone-sparse-english-v0`: Sparse embedding model for keyword or hybrid semantic/keyword search
|
|
623
|
+
|
|
624
|
+
## Integrated Records (Auto-Embedding)
|
|
625
|
+
|
|
626
|
+
For indexes with integrated embedding, use `upsertRecords` to automatically convert text to vectors.
|
|
627
|
+
|
|
628
|
+
### Upsert with Auto-Embedding
|
|
629
|
+
|
|
630
|
+
```typescript
|
|
631
|
+
const pc = new Pinecone();
|
|
632
|
+
const index = pc.index('integrated-index').namespace('my-namespace');
|
|
633
|
+
|
|
634
|
+
await index.upsertRecords([
|
|
635
|
+
{
|
|
636
|
+
id: 'rec1',
|
|
637
|
+
chunk_text: "Apple's first product was the Apple I computer.",
|
|
638
|
+
metadata: { category: 'tech' },
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
id: 'rec2',
|
|
642
|
+
chunk_text: 'The company was founded in 1976.',
|
|
643
|
+
metadata: { category: 'history' },
|
|
644
|
+
},
|
|
645
|
+
]);
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
### Query with Integrated Embedding
|
|
649
|
+
|
|
650
|
+
```typescript
|
|
651
|
+
const results = await index.queryRecords({
|
|
652
|
+
query: 'Tell me about Apple computers',
|
|
653
|
+
topK: 5,
|
|
654
|
+
filter: { category: { $eq: 'tech' } },
|
|
655
|
+
includeMetadata: true,
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
console.log(results.matches);
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
## Namespaces
|
|
662
|
+
|
|
663
|
+
Namespaces partition records within an index and enable multitenancy.
|
|
664
|
+
|
|
665
|
+
### Create Namespace (Implicit)
|
|
666
|
+
|
|
667
|
+
Namespaces are created automatically when you upsert to them:
|
|
668
|
+
|
|
669
|
+
```typescript
|
|
670
|
+
const ns1 = pc.index('my-index').namespace('customer-1');
|
|
671
|
+
await ns1.upsert([{ id: 'vec1', values: [0.1, 0.2, 0.3] }]);
|
|
672
|
+
|
|
673
|
+
const ns2 = pc.index('my-index').namespace('customer-2');
|
|
674
|
+
await ns2.upsert([{ id: 'vec1', values: [0.4, 0.5, 0.6] }]);
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
### List Namespaces
|
|
678
|
+
|
|
679
|
+
```typescript
|
|
680
|
+
const stats = await index.describeIndexStats();
|
|
681
|
+
console.log(Object.keys(stats.namespaces));
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
### Default Namespace
|
|
685
|
+
|
|
686
|
+
If no namespace is specified, vectors are stored in the `"__default__"` namespace:
|
|
687
|
+
|
|
688
|
+
```typescript
|
|
689
|
+
const index = pc.index('my-index');
|
|
690
|
+
// This uses the default namespace
|
|
691
|
+
await index.upsert([{ id: 'vec1', values: [0.1, 0.2, 0.3] }]);
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
## Reranking
|
|
695
|
+
|
|
696
|
+
Use Pinecone's reranking models to reorder results by relevance.
|
|
697
|
+
|
|
698
|
+
### Rerank Results
|
|
699
|
+
|
|
700
|
+
```typescript
|
|
701
|
+
import { Pinecone } from '@pinecone-database/pinecone';
|
|
702
|
+
|
|
703
|
+
const pc = new Pinecone();
|
|
704
|
+
|
|
705
|
+
const reranked = await pc.inference.rerank({
|
|
706
|
+
model: 'bge-reranker-v2-m3',
|
|
707
|
+
query: 'What is the capital of France?',
|
|
708
|
+
documents: [
|
|
709
|
+
{ id: 'doc1', text: 'Paris is the capital of France.' },
|
|
710
|
+
{ id: 'doc2', text: 'London is the capital of England.' },
|
|
711
|
+
{ id: 'doc3', text: 'Berlin is the capital of Germany.' },
|
|
712
|
+
],
|
|
713
|
+
topN: 2,
|
|
714
|
+
returnDocuments: true,
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
console.log(reranked);
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
## Collections (Backups)
|
|
721
|
+
|
|
722
|
+
Collections are static snapshots of an index that can be used to create new indexes.
|
|
723
|
+
|
|
724
|
+
### Create Collection
|
|
725
|
+
|
|
726
|
+
```typescript
|
|
727
|
+
const pc = new Pinecone();
|
|
728
|
+
|
|
729
|
+
await pc.createCollection({
|
|
730
|
+
name: 'my-collection',
|
|
731
|
+
source: 'my-index',
|
|
732
|
+
});
|
|
733
|
+
```
|
|
734
|
+
|
|
735
|
+
### List Collections
|
|
736
|
+
|
|
737
|
+
```typescript
|
|
738
|
+
const collections = await pc.listCollections();
|
|
739
|
+
console.log(collections);
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
### Create Index from Collection
|
|
743
|
+
|
|
744
|
+
```typescript
|
|
745
|
+
await pc.createIndex({
|
|
746
|
+
name: 'new-index-from-backup',
|
|
747
|
+
dimension: 1536,
|
|
748
|
+
metric: 'cosine',
|
|
749
|
+
spec: {
|
|
750
|
+
serverless: {
|
|
751
|
+
cloud: 'aws',
|
|
752
|
+
region: 'us-west-2',
|
|
753
|
+
},
|
|
754
|
+
},
|
|
755
|
+
sourceCollection: 'my-collection',
|
|
756
|
+
});
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
### Delete Collection
|
|
760
|
+
|
|
761
|
+
```typescript
|
|
762
|
+
await pc.deleteCollection('my-collection');
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
## Error Handling
|
|
766
|
+
|
|
767
|
+
### Basic Error Handling
|
|
768
|
+
|
|
769
|
+
```typescript
|
|
770
|
+
import { Pinecone, PineconeConnectionError } from '@pinecone-database/pinecone';
|
|
771
|
+
|
|
772
|
+
const pc = new Pinecone();
|
|
773
|
+
const index = pc.index('my-index');
|
|
774
|
+
|
|
775
|
+
try {
|
|
776
|
+
await index.query({
|
|
777
|
+
vector: [0.1, 0.2, 0.3],
|
|
778
|
+
topK: 10,
|
|
779
|
+
});
|
|
780
|
+
} catch (error) {
|
|
781
|
+
if (error instanceof PineconeConnectionError) {
|
|
782
|
+
console.error('Connection error:', error.message);
|
|
783
|
+
} else {
|
|
784
|
+
console.error('Unexpected error:', error);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
```
|
|
788
|
+
|
|
789
|
+
### Retry Configuration
|
|
790
|
+
|
|
791
|
+
```typescript
|
|
792
|
+
const pc = new Pinecone({
|
|
793
|
+
apiKey: process.env.PINECONE_API_KEY,
|
|
794
|
+
maxRetries: 5, // Increase retries for operations
|
|
795
|
+
});
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
## Performance Best Practices
|
|
799
|
+
|
|
800
|
+
### Batch Operations
|
|
801
|
+
|
|
802
|
+
Always batch upsert operations for better throughput:
|
|
803
|
+
|
|
804
|
+
```typescript
|
|
805
|
+
// Good: Batch upsert
|
|
806
|
+
const vectors = generateVectors(1000);
|
|
807
|
+
await index.upsert(vectors);
|
|
808
|
+
|
|
809
|
+
// Bad: Individual upserts
|
|
810
|
+
for (const vector of vectors) {
|
|
811
|
+
await index.upsert([vector]); // Don't do this
|
|
812
|
+
}
|
|
813
|
+
```
|
|
814
|
+
|
|
815
|
+
### Parallel Requests
|
|
816
|
+
|
|
817
|
+
Use Promise.all for independent parallel operations:
|
|
818
|
+
|
|
819
|
+
```typescript
|
|
820
|
+
const [stats, listResult, queryResult] = await Promise.all([
|
|
821
|
+
index.describeIndexStats(),
|
|
822
|
+
pc.listIndexes(),
|
|
823
|
+
index.query({ vector: [0.1, 0.2, 0.3], topK: 5 }),
|
|
824
|
+
]);
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
### Connection Reuse
|
|
828
|
+
|
|
829
|
+
Reuse the index connection instead of recreating it:
|
|
830
|
+
|
|
831
|
+
```typescript
|
|
832
|
+
// Good: Create once, reuse
|
|
833
|
+
const index = pc.index('my-index');
|
|
834
|
+
for (let i = 0; i < 100; i++) {
|
|
835
|
+
await index.query({ vector: getVector(i), topK: 5 });
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
// Bad: Recreate each time
|
|
839
|
+
for (let i = 0; i < 100; i++) {
|
|
840
|
+
const index = pc.index('my-index'); // Don't do this
|
|
841
|
+
await index.query({ vector: getVector(i), topK: 5 });
|
|
842
|
+
}
|
|
843
|
+
```
|
|
844
|
+
|
|
845
|
+
## Metadata Filtering Operators
|
|
846
|
+
|
|
847
|
+
Pinecone supports MongoDB-style query operators for metadata filtering:
|
|
848
|
+
|
|
849
|
+
- `$eq`: Equal to
|
|
850
|
+
- `$ne`: Not equal to
|
|
851
|
+
- `$gt`: Greater than
|
|
852
|
+
- `$gte`: Greater than or equal to
|
|
853
|
+
- `$lt`: Less than
|
|
854
|
+
- `$lte`: Less than or equal to
|
|
855
|
+
- `$in`: In array
|
|
856
|
+
- `$nin`: Not in array
|
|
857
|
+
- `$exists`: Field exists
|
|
858
|
+
- `$and`: Logical AND
|
|
859
|
+
- `$or`: Logical OR
|
|
860
|
+
|
|
861
|
+
### Example: Complex Filter
|
|
862
|
+
|
|
863
|
+
```typescript
|
|
864
|
+
const results = await index.query({
|
|
865
|
+
vector: [0.1, 0.2, 0.3],
|
|
866
|
+
topK: 10,
|
|
867
|
+
filter: {
|
|
868
|
+
$and: [
|
|
869
|
+
{ year: { $gte: 2020, $lte: 2023 } },
|
|
870
|
+
{
|
|
871
|
+
$or: [
|
|
872
|
+
{ genre: { $eq: 'comedy' } },
|
|
873
|
+
{ genre: { $eq: 'drama' } },
|
|
874
|
+
],
|
|
875
|
+
},
|
|
876
|
+
{ rating: { $exists: true } },
|
|
877
|
+
],
|
|
878
|
+
},
|
|
879
|
+
includeMetadata: true,
|
|
880
|
+
});
|
|
881
|
+
```
|
|
882
|
+
|
|
883
|
+
## Limits and Constraints
|
|
884
|
+
|
|
885
|
+
- **Max vectors per upsert**: 1,000 records (or 2 MB per batch)
|
|
886
|
+
- **Max vectors per upsert (with text)**: 96 records
|
|
887
|
+
- **Metadata size per vector**: 40 KB max
|
|
888
|
+
- **Record ID length**: 512 characters max
|
|
889
|
+
- **Dense vector dimensions**: Up to 20,000
|
|
890
|
+
- **Sparse vector non-zero values**: 2,048 max
|
|
891
|
+
- **Top-K query limit**: 10,000
|
|
892
|
+
|
|
893
|
+
## Common Patterns
|
|
894
|
+
|
|
895
|
+
### Pattern: Upsert and Query Flow
|
|
896
|
+
|
|
897
|
+
```typescript
|
|
898
|
+
import { Pinecone } from '@pinecone-database/pinecone';
|
|
899
|
+
|
|
900
|
+
const pc = new Pinecone();
|
|
901
|
+
|
|
902
|
+
// Create index
|
|
903
|
+
await pc.createIndex({
|
|
904
|
+
name: 'example-index',
|
|
905
|
+
dimension: 1536,
|
|
906
|
+
metric: 'cosine',
|
|
907
|
+
spec: {
|
|
908
|
+
serverless: { cloud: 'aws', region: 'us-west-2' },
|
|
909
|
+
},
|
|
910
|
+
waitUntilReady: true,
|
|
911
|
+
});
|
|
912
|
+
|
|
913
|
+
// Connect and upsert
|
|
914
|
+
const index = pc.index('example-index');
|
|
915
|
+
await index.upsert([
|
|
916
|
+
{
|
|
917
|
+
id: 'doc1',
|
|
918
|
+
values: [0.1, 0.2, 0.3], // ... 1536 dimensions
|
|
919
|
+
metadata: { title: 'Document 1', category: 'A' },
|
|
920
|
+
},
|
|
921
|
+
]);
|
|
922
|
+
|
|
923
|
+
// Query
|
|
924
|
+
const results = await index.query({
|
|
925
|
+
vector: [0.1, 0.2, 0.3], // ... 1536 dimensions
|
|
926
|
+
topK: 5,
|
|
927
|
+
includeMetadata: true,
|
|
928
|
+
});
|
|
929
|
+
|
|
930
|
+
console.log(results.matches);
|
|
931
|
+
```
|
|
932
|
+
|
|
933
|
+
### Pattern: Multi-Tenant with Namespaces
|
|
934
|
+
|
|
935
|
+
```typescript
|
|
936
|
+
const pc = new Pinecone();
|
|
937
|
+
const index = pc.index('multi-tenant-index');
|
|
938
|
+
|
|
939
|
+
// Tenant 1
|
|
940
|
+
const tenant1 = index.namespace('tenant-1');
|
|
941
|
+
await tenant1.upsert([
|
|
942
|
+
{ id: 'vec1', values: [0.1, 0.2, 0.3], metadata: { user: 'user1' } },
|
|
943
|
+
]);
|
|
944
|
+
|
|
945
|
+
// Tenant 2
|
|
946
|
+
const tenant2 = index.namespace('tenant-2');
|
|
947
|
+
await tenant2.upsert([
|
|
948
|
+
{ id: 'vec1', values: [0.4, 0.5, 0.6], metadata: { user: 'user2' } },
|
|
949
|
+
]);
|
|
950
|
+
|
|
951
|
+
// Query tenant-specific data
|
|
952
|
+
const tenant1Results = await tenant1.query({
|
|
953
|
+
vector: [0.1, 0.2, 0.3],
|
|
954
|
+
topK: 5,
|
|
955
|
+
});
|
|
956
|
+
```
|
|
957
|
+
|
|
958
|
+
### Pattern: Hybrid Search with Weighting
|
|
959
|
+
|
|
960
|
+
```typescript
|
|
961
|
+
// Alpha controls dense vs sparse weighting
|
|
962
|
+
// alpha=1 is pure dense, alpha=0 is pure sparse
|
|
963
|
+
const alpha = 0.7;
|
|
964
|
+
|
|
965
|
+
const denseVector = [0.1, 0.2, 0.3];
|
|
966
|
+
const sparseVector = {
|
|
967
|
+
indices: [10, 45, 16],
|
|
968
|
+
values: [0.5, 0.5, 0.2],
|
|
969
|
+
};
|
|
970
|
+
|
|
971
|
+
// Apply weighting
|
|
972
|
+
const weightedDense = denseVector.map(v => v * alpha);
|
|
973
|
+
const weightedSparse = {
|
|
974
|
+
indices: sparseVector.indices,
|
|
975
|
+
values: sparseVector.values.map(v => v * (1 - alpha)),
|
|
976
|
+
};
|
|
977
|
+
|
|
978
|
+
const results = await index.query({
|
|
979
|
+
vector: weightedDense,
|
|
980
|
+
sparseVector: weightedSparse,
|
|
981
|
+
topK: 10,
|
|
982
|
+
includeMetadata: true,
|
|
983
|
+
});
|
|
984
|
+
```
|