pgvector 0.3.5__py3-none-any.whl
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.
- pgvector/asyncpg/__init__.py +9 -0
- pgvector/asyncpg/register.py +31 -0
- pgvector/django/__init__.py +26 -0
- pgvector/django/bit.py +32 -0
- pgvector/django/extensions.py +6 -0
- pgvector/django/functions.py +55 -0
- pgvector/django/halfvec.py +60 -0
- pgvector/django/indexes.py +46 -0
- pgvector/django/sparsevec.py +55 -0
- pgvector/django/vector.py +73 -0
- pgvector/peewee/__init__.py +14 -0
- pgvector/peewee/bit.py +21 -0
- pgvector/peewee/halfvec.py +34 -0
- pgvector/peewee/sparsevec.py +34 -0
- pgvector/peewee/vector.py +34 -0
- pgvector/psycopg/__init__.py +11 -0
- pgvector/psycopg/bit.py +31 -0
- pgvector/psycopg/halfvec.py +53 -0
- pgvector/psycopg/register.py +37 -0
- pgvector/psycopg/sparsevec.py +53 -0
- pgvector/psycopg/vector.py +58 -0
- pgvector/psycopg2/__init__.py +8 -0
- pgvector/psycopg2/halfvec.py +20 -0
- pgvector/psycopg2/register.py +28 -0
- pgvector/psycopg2/sparsevec.py +20 -0
- pgvector/psycopg2/vector.py +21 -0
- pgvector/sqlalchemy/__init__.py +19 -0
- pgvector/sqlalchemy/bit.py +26 -0
- pgvector/sqlalchemy/functions.py +14 -0
- pgvector/sqlalchemy/halfvec.py +51 -0
- pgvector/sqlalchemy/sparsevec.py +51 -0
- pgvector/sqlalchemy/vector.py +51 -0
- pgvector/utils/__init__.py +11 -0
- pgvector/utils/bit.py +61 -0
- pgvector/utils/halfvec.py +78 -0
- pgvector/utils/sparsevec.py +156 -0
- pgvector/utils/vector.py +78 -0
- pgvector-0.3.5.dist-info/LICENSE.txt +21 -0
- pgvector-0.3.5.dist-info/METADATA +554 -0
- pgvector-0.3.5.dist-info/RECORD +42 -0
- pgvector-0.3.5.dist-info/WHEEL +5 -0
- pgvector-0.3.5.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,554 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: pgvector
|
|
3
|
+
Version: 0.3.5
|
|
4
|
+
Summary: pgvector support for Python
|
|
5
|
+
Author-email: Andrew Kane <andrew@ankane.org>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/pgvector/pgvector-python
|
|
8
|
+
Requires-Python: >=3.8
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE.txt
|
|
11
|
+
Requires-Dist: numpy
|
|
12
|
+
|
|
13
|
+
# pgvector-python
|
|
14
|
+
|
|
15
|
+
[pgvector](https://github.com/pgvector/pgvector) support for Python
|
|
16
|
+
|
|
17
|
+
Supports [Django](https://github.com/django/django), [SQLAlchemy](https://github.com/sqlalchemy/sqlalchemy), [SQLModel](https://github.com/tiangolo/sqlmodel), [Psycopg 3](https://github.com/psycopg/psycopg), [Psycopg 2](https://github.com/psycopg/psycopg2), [asyncpg](https://github.com/MagicStack/asyncpg), and [Peewee](https://github.com/coleifer/peewee)
|
|
18
|
+
|
|
19
|
+
[](https://github.com/pgvector/pgvector-python/actions)
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
Run:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
pip install pgvector
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
And follow the instructions for your database library:
|
|
30
|
+
|
|
31
|
+
- [Django](#django)
|
|
32
|
+
- [SQLAlchemy](#sqlalchemy)
|
|
33
|
+
- [SQLModel](#sqlmodel)
|
|
34
|
+
- [Psycopg 3](#psycopg-3)
|
|
35
|
+
- [Psycopg 2](#psycopg-2)
|
|
36
|
+
- [asyncpg](#asyncpg)
|
|
37
|
+
- [Peewee](#peewee)
|
|
38
|
+
|
|
39
|
+
Or check out some examples:
|
|
40
|
+
|
|
41
|
+
- [Embeddings](https://github.com/pgvector/pgvector-python/blob/master/examples/openai/example.py) with OpenAI
|
|
42
|
+
- [Binary embeddings](https://github.com/pgvector/pgvector-python/blob/master/examples/cohere/example.py) with Cohere
|
|
43
|
+
- [Sentence embeddings](https://github.com/pgvector/pgvector-python/blob/master/examples/sentence_transformers/example.py) with SentenceTransformers
|
|
44
|
+
- [Hybrid search](https://github.com/pgvector/pgvector-python/blob/master/examples/hybrid_search/rrf.py) with SentenceTransformers (Reciprocal Rank Fusion)
|
|
45
|
+
- [Hybrid search](https://github.com/pgvector/pgvector-python/blob/master/examples/hybrid_search/cross_encoder.py) with SentenceTransformers (cross-encoder)
|
|
46
|
+
- [Sparse search](https://github.com/pgvector/pgvector-python/blob/master/examples/sparse_search/example.py) with Transformers
|
|
47
|
+
- [Late interaction search](https://github.com/pgvector/pgvector-python/blob/master/examples/colbert/exact.py) with ColBERT
|
|
48
|
+
- [Image search](https://github.com/pgvector/pgvector-python/blob/master/examples/image_search/example.py) with PyTorch
|
|
49
|
+
- [Image search](https://github.com/pgvector/pgvector-python/blob/master/examples/imagehash/example.py) with perceptual hashing
|
|
50
|
+
- [Morgan fingerprints](https://github.com/pgvector/pgvector-python/blob/master/examples/rdkit/example.py) with RDKit
|
|
51
|
+
- [Topic modeling](https://github.com/pgvector/pgvector-python/blob/master/examples/gensim/example.py) with Gensim
|
|
52
|
+
- [Implicit feedback recommendations](https://github.com/pgvector/pgvector-python/blob/master/examples/implicit/example.py) with Implicit
|
|
53
|
+
- [Explicit feedback recommendations](https://github.com/pgvector/pgvector-python/blob/master/examples/surprise/example.py) with Surprise
|
|
54
|
+
- [Recommendations](https://github.com/pgvector/pgvector-python/blob/master/examples/lightfm/example.py) with LightFM
|
|
55
|
+
- [Horizontal scaling](https://github.com/pgvector/pgvector-python/blob/master/examples/citus/example.py) with Citus
|
|
56
|
+
- [Bulk loading](https://github.com/pgvector/pgvector-python/blob/master/examples/loading/example.py) with `COPY`
|
|
57
|
+
|
|
58
|
+
## Django
|
|
59
|
+
|
|
60
|
+
Create a migration to enable the extension
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from pgvector.django import VectorExtension
|
|
64
|
+
|
|
65
|
+
class Migration(migrations.Migration):
|
|
66
|
+
operations = [
|
|
67
|
+
VectorExtension()
|
|
68
|
+
]
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Add a vector field to your model
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
from pgvector.django import VectorField
|
|
75
|
+
|
|
76
|
+
class Item(models.Model):
|
|
77
|
+
embedding = VectorField(dimensions=3)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Also supports `HalfVectorField`, `BitField`, and `SparseVectorField`
|
|
81
|
+
|
|
82
|
+
Insert a vector
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
item = Item(embedding=[1, 2, 3])
|
|
86
|
+
item.save()
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Get the nearest neighbors to a vector
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from pgvector.django import L2Distance
|
|
93
|
+
|
|
94
|
+
Item.objects.order_by(L2Distance('embedding', [3, 1, 2]))[:5]
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Also supports `MaxInnerProduct`, `CosineDistance`, `L1Distance`, `HammingDistance`, and `JaccardDistance`
|
|
98
|
+
|
|
99
|
+
Get the distance
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
Item.objects.annotate(distance=L2Distance('embedding', [3, 1, 2]))
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Get items within a certain distance
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
Item.objects.alias(distance=L2Distance('embedding', [3, 1, 2])).filter(distance__lt=5)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Average vectors
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from django.db.models import Avg
|
|
115
|
+
|
|
116
|
+
Item.objects.aggregate(Avg('embedding'))
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Also supports `Sum`
|
|
120
|
+
|
|
121
|
+
Add an approximate index
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
from pgvector.django import HnswIndex, IvfflatIndex
|
|
125
|
+
|
|
126
|
+
class Item(models.Model):
|
|
127
|
+
class Meta:
|
|
128
|
+
indexes = [
|
|
129
|
+
HnswIndex(
|
|
130
|
+
name='my_index',
|
|
131
|
+
fields=['embedding'],
|
|
132
|
+
m=16,
|
|
133
|
+
ef_construction=64,
|
|
134
|
+
opclasses=['vector_l2_ops']
|
|
135
|
+
),
|
|
136
|
+
# or
|
|
137
|
+
IvfflatIndex(
|
|
138
|
+
name='my_index',
|
|
139
|
+
fields=['embedding'],
|
|
140
|
+
lists=100,
|
|
141
|
+
opclasses=['vector_l2_ops']
|
|
142
|
+
)
|
|
143
|
+
]
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Use `vector_ip_ops` for inner product and `vector_cosine_ops` for cosine distance
|
|
147
|
+
|
|
148
|
+
## SQLAlchemy
|
|
149
|
+
|
|
150
|
+
Enable the extension
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
session.execute(text('CREATE EXTENSION IF NOT EXISTS vector'))
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Add a vector column
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
from pgvector.sqlalchemy import Vector
|
|
160
|
+
|
|
161
|
+
class Item(Base):
|
|
162
|
+
embedding = mapped_column(Vector(3))
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Also supports `HALFVEC`, `BIT`, and `SPARSEVEC`
|
|
166
|
+
|
|
167
|
+
Insert a vector
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
item = Item(embedding=[1, 2, 3])
|
|
171
|
+
session.add(item)
|
|
172
|
+
session.commit()
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Get the nearest neighbors to a vector
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
session.scalars(select(Item).order_by(Item.embedding.l2_distance([3, 1, 2])).limit(5))
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Also supports `max_inner_product`, `cosine_distance`, `l1_distance`, `hamming_distance`, and `jaccard_distance`
|
|
182
|
+
|
|
183
|
+
Get the distance
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
session.scalars(select(Item.embedding.l2_distance([3, 1, 2])))
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Get items within a certain distance
|
|
190
|
+
|
|
191
|
+
```python
|
|
192
|
+
session.scalars(select(Item).filter(Item.embedding.l2_distance([3, 1, 2]) < 5))
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Average vectors
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
from pgvector.sqlalchemy import avg
|
|
199
|
+
|
|
200
|
+
session.scalars(select(func.avg(Item.embedding))).first()
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Also supports `sum`
|
|
204
|
+
|
|
205
|
+
Add an approximate index
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
index = Index(
|
|
209
|
+
'my_index',
|
|
210
|
+
Item.embedding,
|
|
211
|
+
postgresql_using='hnsw',
|
|
212
|
+
postgresql_with={'m': 16, 'ef_construction': 64},
|
|
213
|
+
postgresql_ops={'embedding': 'vector_l2_ops'}
|
|
214
|
+
)
|
|
215
|
+
# or
|
|
216
|
+
index = Index(
|
|
217
|
+
'my_index',
|
|
218
|
+
Item.embedding,
|
|
219
|
+
postgresql_using='ivfflat',
|
|
220
|
+
postgresql_with={'lists': 100},
|
|
221
|
+
postgresql_ops={'embedding': 'vector_l2_ops'}
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
index.create(engine)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Use `vector_ip_ops` for inner product and `vector_cosine_ops` for cosine distance
|
|
228
|
+
|
|
229
|
+
## SQLModel
|
|
230
|
+
|
|
231
|
+
Enable the extension
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
session.exec(text('CREATE EXTENSION IF NOT EXISTS vector'))
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Add a vector column
|
|
238
|
+
|
|
239
|
+
```python
|
|
240
|
+
from pgvector.sqlalchemy import Vector
|
|
241
|
+
from sqlalchemy import Column
|
|
242
|
+
|
|
243
|
+
class Item(SQLModel, table=True):
|
|
244
|
+
embedding: Any = Field(sa_column=Column(Vector(3)))
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Also supports `HALFVEC`, `BIT`, and `SPARSEVEC`
|
|
248
|
+
|
|
249
|
+
Insert a vector
|
|
250
|
+
|
|
251
|
+
```python
|
|
252
|
+
item = Item(embedding=[1, 2, 3])
|
|
253
|
+
session.add(item)
|
|
254
|
+
session.commit()
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Get the nearest neighbors to a vector
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
session.exec(select(Item).order_by(Item.embedding.l2_distance([3, 1, 2])).limit(5))
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Also supports `max_inner_product`, `cosine_distance`, `l1_distance`, `hamming_distance`, and `jaccard_distance`
|
|
264
|
+
|
|
265
|
+
Get the distance
|
|
266
|
+
|
|
267
|
+
```python
|
|
268
|
+
session.exec(select(Item.embedding.l2_distance([3, 1, 2])))
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Get items within a certain distance
|
|
272
|
+
|
|
273
|
+
```python
|
|
274
|
+
session.exec(select(Item).filter(Item.embedding.l2_distance([3, 1, 2]) < 5))
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Average vectors
|
|
278
|
+
|
|
279
|
+
```python
|
|
280
|
+
from pgvector.sqlalchemy import avg
|
|
281
|
+
|
|
282
|
+
session.exec(select(func.avg(Item.embedding))).first()
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Also supports `sum`
|
|
286
|
+
|
|
287
|
+
Add an approximate index
|
|
288
|
+
|
|
289
|
+
```python
|
|
290
|
+
from sqlalchemy import Index
|
|
291
|
+
|
|
292
|
+
index = Index(
|
|
293
|
+
'my_index',
|
|
294
|
+
Item.embedding,
|
|
295
|
+
postgresql_using='hnsw',
|
|
296
|
+
postgresql_with={'m': 16, 'ef_construction': 64},
|
|
297
|
+
postgresql_ops={'embedding': 'vector_l2_ops'}
|
|
298
|
+
)
|
|
299
|
+
# or
|
|
300
|
+
index = Index(
|
|
301
|
+
'my_index',
|
|
302
|
+
Item.embedding,
|
|
303
|
+
postgresql_using='ivfflat',
|
|
304
|
+
postgresql_with={'lists': 100},
|
|
305
|
+
postgresql_ops={'embedding': 'vector_l2_ops'}
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
index.create(engine)
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Use `vector_ip_ops` for inner product and `vector_cosine_ops` for cosine distance
|
|
312
|
+
|
|
313
|
+
## Psycopg 3
|
|
314
|
+
|
|
315
|
+
Enable the extension
|
|
316
|
+
|
|
317
|
+
```python
|
|
318
|
+
conn.execute('CREATE EXTENSION IF NOT EXISTS vector')
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Register the vector type with your connection
|
|
322
|
+
|
|
323
|
+
```python
|
|
324
|
+
from pgvector.psycopg import register_vector
|
|
325
|
+
|
|
326
|
+
register_vector(conn)
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
For [async connections](https://www.psycopg.org/psycopg3/docs/advanced/async.html), use
|
|
330
|
+
|
|
331
|
+
```python
|
|
332
|
+
from pgvector.psycopg import register_vector_async
|
|
333
|
+
|
|
334
|
+
await register_vector_async(conn)
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
Create a table
|
|
338
|
+
|
|
339
|
+
```python
|
|
340
|
+
conn.execute('CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3))')
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Insert a vector
|
|
344
|
+
|
|
345
|
+
```python
|
|
346
|
+
embedding = np.array([1, 2, 3])
|
|
347
|
+
conn.execute('INSERT INTO items (embedding) VALUES (%s)', (embedding,))
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Get the nearest neighbors to a vector
|
|
351
|
+
|
|
352
|
+
```python
|
|
353
|
+
conn.execute('SELECT * FROM items ORDER BY embedding <-> %s LIMIT 5', (embedding,)).fetchall()
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
Add an approximate index
|
|
357
|
+
|
|
358
|
+
```python
|
|
359
|
+
conn.execute('CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)')
|
|
360
|
+
# or
|
|
361
|
+
conn.execute('CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100)')
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
Use `vector_ip_ops` for inner product and `vector_cosine_ops` for cosine distance
|
|
365
|
+
|
|
366
|
+
## Psycopg 2
|
|
367
|
+
|
|
368
|
+
Enable the extension
|
|
369
|
+
|
|
370
|
+
```python
|
|
371
|
+
cur = conn.cursor()
|
|
372
|
+
cur.execute('CREATE EXTENSION IF NOT EXISTS vector')
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
Register the vector type with your connection or cursor
|
|
376
|
+
|
|
377
|
+
```python
|
|
378
|
+
from pgvector.psycopg2 import register_vector
|
|
379
|
+
|
|
380
|
+
register_vector(conn)
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
Create a table
|
|
384
|
+
|
|
385
|
+
```python
|
|
386
|
+
cur.execute('CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3))')
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
Insert a vector
|
|
390
|
+
|
|
391
|
+
```python
|
|
392
|
+
embedding = np.array([1, 2, 3])
|
|
393
|
+
cur.execute('INSERT INTO items (embedding) VALUES (%s)', (embedding,))
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
Get the nearest neighbors to a vector
|
|
397
|
+
|
|
398
|
+
```python
|
|
399
|
+
cur.execute('SELECT * FROM items ORDER BY embedding <-> %s LIMIT 5', (embedding,))
|
|
400
|
+
cur.fetchall()
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
Add an approximate index
|
|
404
|
+
|
|
405
|
+
```python
|
|
406
|
+
cur.execute('CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)')
|
|
407
|
+
# or
|
|
408
|
+
cur.execute('CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100)')
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
Use `vector_ip_ops` for inner product and `vector_cosine_ops` for cosine distance
|
|
412
|
+
|
|
413
|
+
## asyncpg
|
|
414
|
+
|
|
415
|
+
Enable the extension
|
|
416
|
+
|
|
417
|
+
```python
|
|
418
|
+
await conn.execute('CREATE EXTENSION IF NOT EXISTS vector')
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
Register the vector type with your connection
|
|
422
|
+
|
|
423
|
+
```python
|
|
424
|
+
from pgvector.asyncpg import register_vector
|
|
425
|
+
|
|
426
|
+
await register_vector(conn)
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
or your pool
|
|
430
|
+
|
|
431
|
+
```python
|
|
432
|
+
async def init(conn):
|
|
433
|
+
await register_vector(conn)
|
|
434
|
+
|
|
435
|
+
pool = await asyncpg.create_pool(..., init=init)
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
Create a table
|
|
439
|
+
|
|
440
|
+
```python
|
|
441
|
+
await conn.execute('CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3))')
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
Insert a vector
|
|
445
|
+
|
|
446
|
+
```python
|
|
447
|
+
embedding = np.array([1, 2, 3])
|
|
448
|
+
await conn.execute('INSERT INTO items (embedding) VALUES ($1)', embedding)
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
Get the nearest neighbors to a vector
|
|
452
|
+
|
|
453
|
+
```python
|
|
454
|
+
await conn.fetch('SELECT * FROM items ORDER BY embedding <-> $1 LIMIT 5', embedding)
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
Add an approximate index
|
|
458
|
+
|
|
459
|
+
```python
|
|
460
|
+
await conn.execute('CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)')
|
|
461
|
+
# or
|
|
462
|
+
await conn.execute('CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100)')
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
Use `vector_ip_ops` for inner product and `vector_cosine_ops` for cosine distance
|
|
466
|
+
|
|
467
|
+
## Peewee
|
|
468
|
+
|
|
469
|
+
Add a vector column
|
|
470
|
+
|
|
471
|
+
```python
|
|
472
|
+
from pgvector.peewee import VectorField
|
|
473
|
+
|
|
474
|
+
class Item(BaseModel):
|
|
475
|
+
embedding = VectorField(dimensions=3)
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
Also supports `HalfVectorField`, `FixedBitField`, and `SparseVectorField`
|
|
479
|
+
|
|
480
|
+
Insert a vector
|
|
481
|
+
|
|
482
|
+
```python
|
|
483
|
+
item = Item.create(embedding=[1, 2, 3])
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
Get the nearest neighbors to a vector
|
|
487
|
+
|
|
488
|
+
```python
|
|
489
|
+
Item.select().order_by(Item.embedding.l2_distance([3, 1, 2])).limit(5)
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
Also supports `max_inner_product`, `cosine_distance`, `l1_distance`, `hamming_distance`, and `jaccard_distance`
|
|
493
|
+
|
|
494
|
+
Get the distance
|
|
495
|
+
|
|
496
|
+
```python
|
|
497
|
+
Item.select(Item.embedding.l2_distance([3, 1, 2]).alias('distance'))
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
Get items within a certain distance
|
|
501
|
+
|
|
502
|
+
```python
|
|
503
|
+
Item.select().where(Item.embedding.l2_distance([3, 1, 2]) < 5)
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
Average vectors
|
|
507
|
+
|
|
508
|
+
```python
|
|
509
|
+
from peewee import fn
|
|
510
|
+
|
|
511
|
+
Item.select(fn.avg(Item.embedding).coerce(True)).scalar()
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
Also supports `sum`
|
|
515
|
+
|
|
516
|
+
Add an approximate index
|
|
517
|
+
|
|
518
|
+
```python
|
|
519
|
+
Item.add_index('embedding vector_l2_ops', using='hnsw')
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
Use `vector_ip_ops` for inner product and `vector_cosine_ops` for cosine distance
|
|
523
|
+
|
|
524
|
+
## History
|
|
525
|
+
|
|
526
|
+
View the [changelog](https://github.com/pgvector/pgvector-python/blob/master/CHANGELOG.md)
|
|
527
|
+
|
|
528
|
+
## Contributing
|
|
529
|
+
|
|
530
|
+
Everyone is encouraged to help improve this project. Here are a few ways you can help:
|
|
531
|
+
|
|
532
|
+
- [Report bugs](https://github.com/pgvector/pgvector-python/issues)
|
|
533
|
+
- Fix bugs and [submit pull requests](https://github.com/pgvector/pgvector-python/pulls)
|
|
534
|
+
- Write, clarify, or fix documentation
|
|
535
|
+
- Suggest or add new features
|
|
536
|
+
|
|
537
|
+
To get started with development:
|
|
538
|
+
|
|
539
|
+
```sh
|
|
540
|
+
git clone https://github.com/pgvector/pgvector-python.git
|
|
541
|
+
cd pgvector-python
|
|
542
|
+
pip install -r requirements.txt
|
|
543
|
+
createdb pgvector_python_test
|
|
544
|
+
pytest
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
To run an example:
|
|
548
|
+
|
|
549
|
+
```sh
|
|
550
|
+
cd examples/loading
|
|
551
|
+
pip install -r requirements.txt
|
|
552
|
+
createdb pgvector_example
|
|
553
|
+
python3 example.py
|
|
554
|
+
```
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
pgvector/asyncpg/__init__.py,sha256=nPEfolmn6hf2gmonE1sCne051hd28biWhlSRimDy0AI,180
|
|
2
|
+
pgvector/asyncpg/register.py,sha256=33xZD3SZjkDUFcEuVvVVQPZLEkpBVZZE2iZeWbLa1lc,835
|
|
3
|
+
pgvector/django/__init__.py,sha256=omSXhf85Nazw2e1h2HzgxphL-MNTZUg7A_hwQ6nXBCo,701
|
|
4
|
+
pgvector/django/bit.py,sha256=QjWHD4FhsveLQ8r3Q8SYDoe-zIYnhHR0W7HDLGx87Dc,935
|
|
5
|
+
pgvector/django/extensions.py,sha256=JAtn_FCIST0DWJtDPZAQ-MygbAkKEiL0ZsA2QbYITRo,158
|
|
6
|
+
pgvector/django/functions.py,sha256=QC6tiWErauN7EtbYqISiwJcpSGnxEW9qOhUBmwmGeoY,1364
|
|
7
|
+
pgvector/django/halfvec.py,sha256=XNr54sddUquK3yDOfJT8BJHbRrEGjN7bwAnRKi_rOgM,1825
|
|
8
|
+
pgvector/django/indexes.py,sha256=purT3nhq_CjHWUe-c3loCyK1XrWtZJ8pIq2wl975aSY,1440
|
|
9
|
+
pgvector/django/sparsevec.py,sha256=KJlGF_VAxSV1eSOHPzfT4uNhCGDMBqjjANJPq2E7osE,1675
|
|
10
|
+
pgvector/django/vector.py,sha256=xASXG7KGr65HsvsLYYrJfwv6azbDOdPcdmw9QLOHayA,2215
|
|
11
|
+
pgvector/peewee/__init__.py,sha256=tANx57_gHFXgJLnr7GhD5j_xhsCosZ4GWBpdG76FNnY,326
|
|
12
|
+
pgvector/peewee/bit.py,sha256=ZK6_RDDj46aAfYyxgXrwXYmHfPZpp5P5aA-CLt0M61Q,619
|
|
13
|
+
pgvector/peewee/halfvec.py,sha256=NY3Wz79QbkKJdmQ_ZrkAqayQutQaO3iR5JBZ00sbMAE,969
|
|
14
|
+
pgvector/peewee/sparsevec.py,sha256=SRDkw1_aWTVHOAXz3LYPMtDvIVlk5ByPcbDKkg1kR_0,981
|
|
15
|
+
pgvector/peewee/vector.py,sha256=HXPj77K70jU7Vk33TVQLkDrp3995a_wygXkjyszDzTM,948
|
|
16
|
+
pgvector/psycopg/__init__.py,sha256=ggPIFt-dlT9T4vCbzLfxReYqdUyFUx2n3J0p2kRZvek,248
|
|
17
|
+
pgvector/psycopg/bit.py,sha256=ad9XneEmlCMEZi-1HN41mrTGogJmINtS7fy_I9Dbem8,712
|
|
18
|
+
pgvector/psycopg/halfvec.py,sha256=A_uVQhXzcDsiK41rB5gmxwqLp7Fjpw-YJYPTED5Va5M,1354
|
|
19
|
+
pgvector/psycopg/register.py,sha256=Ueuc9YKdhSI8Hd2JZIBrGHqp2i5sVW9DIKgS-Xo7Yyk,1107
|
|
20
|
+
pgvector/psycopg/sparsevec.py,sha256=jaOEpcMPknCONMDNmWkQDLcvttemS8aNZGwfbEqHxPQ,1390
|
|
21
|
+
pgvector/psycopg/vector.py,sha256=rUTcBJmyEtcideZ711H8kjVFfFRXLETmRMlGpOCALkA,1521
|
|
22
|
+
pgvector/psycopg2/__init__.py,sha256=ThM3WfiOQfXHv-EY1DbOUNLJkR2RsXmxQzJNoynT4dw,158
|
|
23
|
+
pgvector/psycopg2/halfvec.py,sha256=7JCYfpgflVq-kg4abzPZStxqb4d7u19gd2_X0ZmdGz8,536
|
|
24
|
+
pgvector/psycopg2/register.py,sha256=BLGd6_xZgHGL6T8-lxDC03qkvUCI_HbpiYk46joLoRo,1107
|
|
25
|
+
pgvector/psycopg2/sparsevec.py,sha256=fsIyviFoLIOc1jlMi6R5xWc9NNoKXgNcUKOaOrKlx38,560
|
|
26
|
+
pgvector/psycopg2/vector.py,sha256=v3cwgISpStIS6zJqKcB78xqG0pQq4qCoa9Lbj1o8mCQ,535
|
|
27
|
+
pgvector/sqlalchemy/__init__.py,sha256=CDMSwvIt4mwpuuSMduq3IyvgEp6RLToQClkqOElFY7o,369
|
|
28
|
+
pgvector/sqlalchemy/bit.py,sha256=a-I24dwAR-Uc_vxj32MahDezjQVtUvIoMdPuYpztLIA,722
|
|
29
|
+
pgvector/sqlalchemy/functions.py,sha256=LCxFWiTH-pM4XE2R5QRUg3vJxsxB-LNCGkqCEU6JOfk,272
|
|
30
|
+
pgvector/sqlalchemy/halfvec.py,sha256=jlg3BuwvMrqSuDYJV0sjECEq_tq2n0IjgwtMz-grDak,1538
|
|
31
|
+
pgvector/sqlalchemy/sparsevec.py,sha256=SJPSs0G07Bo8JTzmlO3a0LsYimyYmONynlRQ5Nndxss,1556
|
|
32
|
+
pgvector/sqlalchemy/vector.py,sha256=dw7znnHjIQPblCzWD-uJmVY3HBGDOmw98uB1qkFBmTo,1517
|
|
33
|
+
pgvector/utils/__init__.py,sha256=2qAb4VM3LcsnWwhFvRosnI4QS0KJnTDrY0aoRSXXIcg,193
|
|
34
|
+
pgvector/utils/bit.py,sha256=YMcmqSjdZEhxC4HhSpkCgyYG26WUjM2Qv8JjI2Wu_Ts,1711
|
|
35
|
+
pgvector/utils/halfvec.py,sha256=1yAmQ174UGFIWijfvegVWrr5sjltRAxMUMLmis-9BGc,2013
|
|
36
|
+
pgvector/utils/sparsevec.py,sha256=uo1YfKx35iYuBPC9V3dDHWoAin042q6klOWBgY_Cnhc,4622
|
|
37
|
+
pgvector/utils/vector.py,sha256=upyEMEEJF-o995GAk3UGhDPF9B0Ouv3zHWVZK54M4q8,2079
|
|
38
|
+
pgvector-0.3.5.dist-info/LICENSE.txt,sha256=kzzb1DKtBwp3Pn5-R7YEUm8uH1qHA-D2tjT67Bn_b6M,1083
|
|
39
|
+
pgvector-0.3.5.dist-info/METADATA,sha256=J5ZibepgmNk94dtOOYnO0ZiRyqhz7YSfvs1w98xoc6E,13231
|
|
40
|
+
pgvector-0.3.5.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
41
|
+
pgvector-0.3.5.dist-info/top_level.txt,sha256=xGGaXFRcSRHEhn0HS1FN_UjCWr1G-WSPgxx4a0NJc0M,9
|
|
42
|
+
pgvector-0.3.5.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pgvector
|