vectordb-bench 0.0.8__tar.gz → 0.0.10__tar.gz

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.
Files changed (118) hide show
  1. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/PKG-INFO +4 -3
  2. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/pyproject.toml +3 -2
  3. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/__init__.py +4 -4
  4. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/api.py +1 -0
  5. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/milvus/config.py +6 -2
  6. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/milvus/milvus.py +8 -5
  7. vectordb_bench-0.0.10/vectordb_bench/backend/clients/pgvector/config.py +215 -0
  8. vectordb_bench-0.0.10/vectordb_bench/backend/clients/pgvector/pgvector.py +347 -0
  9. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/runner/serial_runner.py +0 -2
  10. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/components/run_test/caseSelector.py +6 -3
  11. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/const/dbCaseConfigs.py +118 -2
  12. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/models.py +6 -3
  13. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench.egg-info/PKG-INFO +4 -3
  14. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench.egg-info/requires.txt +3 -2
  15. vectordb_bench-0.0.8/vectordb_bench/backend/clients/pgvector/config.py +0 -100
  16. vectordb_bench-0.0.8/vectordb_bench/backend/clients/pgvector/pgvector.py +0 -187
  17. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/.devcontainer/Dockerfile +0 -0
  18. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/.devcontainer/devcontainer.json +0 -0
  19. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/.env.example +0 -0
  20. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/.github/workflows/publish_package_on_release.yml +0 -0
  21. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/.github/workflows/pull_request.yml +0 -0
  22. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/.gitignore +0 -0
  23. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/.ruff.toml +0 -0
  24. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/Dockerfile +0 -0
  25. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/LICENSE +0 -0
  26. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/Makefile +0 -0
  27. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/OWNERS +0 -0
  28. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/README.md +0 -0
  29. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/install/requirements_py3.11.txt +0 -0
  30. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/install.py +0 -0
  31. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/setup.cfg +0 -0
  32. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/tests/conftest.py +0 -0
  33. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/tests/pytest.ini +0 -0
  34. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/tests/test_bench_runner.py +0 -0
  35. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/tests/test_chroma.py +0 -0
  36. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/tests/test_data_source.py +0 -0
  37. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/tests/test_dataset.py +0 -0
  38. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/tests/test_elasticsearch_cloud.py +0 -0
  39. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/tests/test_models.py +0 -0
  40. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/tests/test_redis.py +0 -0
  41. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/tests/test_utils.py +0 -0
  42. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/tests/ut_cases.py +0 -0
  43. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/__main__.py +0 -0
  44. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/__init__.py +0 -0
  45. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/assembler.py +0 -0
  46. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/cases.py +0 -0
  47. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/__init__.py +0 -0
  48. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/chroma/chroma.py +0 -0
  49. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/chroma/config.py +0 -0
  50. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/elastic_cloud/config.py +0 -0
  51. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/elastic_cloud/elastic_cloud.py +0 -0
  52. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/pgvecto_rs/config.py +0 -0
  53. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/pgvecto_rs/pgvecto_rs.py +0 -0
  54. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/pinecone/config.py +0 -0
  55. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/pinecone/pinecone.py +0 -0
  56. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/qdrant_cloud/config.py +0 -0
  57. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/qdrant_cloud/qdrant_cloud.py +0 -0
  58. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/redis/config.py +0 -0
  59. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/redis/redis.py +0 -0
  60. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/weaviate_cloud/config.py +0 -0
  61. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/weaviate_cloud/weaviate_cloud.py +0 -0
  62. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/zilliz_cloud/config.py +0 -0
  63. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/clients/zilliz_cloud/zilliz_cloud.py +0 -0
  64. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/data_source.py +0 -0
  65. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/dataset.py +0 -0
  66. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/result_collector.py +0 -0
  67. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/runner/__init__.py +0 -0
  68. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/runner/mp_runner.py +0 -0
  69. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/task_runner.py +1 -1
  70. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/backend/utils.py +0 -0
  71. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/base.py +0 -0
  72. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/components/check_results/charts.py +0 -0
  73. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/components/check_results/data.py +0 -0
  74. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/components/check_results/expanderStyle.py +0 -0
  75. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/components/check_results/filters.py +0 -0
  76. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/components/check_results/footer.py +0 -0
  77. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/components/check_results/headerIcon.py +0 -0
  78. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/components/check_results/nav.py +0 -0
  79. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/components/check_results/priceTable.py +0 -0
  80. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/components/check_results/stPageConfig.py +0 -0
  81. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/components/get_results/saveAsImage.py +0 -0
  82. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/components/run_test/autoRefresh.py +0 -0
  83. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/components/run_test/dbConfigSetting.py +0 -0
  84. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/components/run_test/dbSelector.py +0 -0
  85. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/components/run_test/generateTasks.py +0 -0
  86. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/components/run_test/hideSidebar.py +0 -0
  87. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/components/run_test/submitTask.py +0 -0
  88. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/const/dbPrices.py +0 -0
  89. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/const/styles.py +0 -0
  90. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/pages/quries_per_dollar.py +0 -0
  91. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/pages/run_test.py +0 -0
  92. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/utils.py +0 -0
  93. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/frontend/vdb_benchmark.py +0 -0
  94. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/interface.py +0 -0
  95. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/log_util.py +0 -0
  96. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/metric.py +0 -0
  97. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/results/ElasticCloud/result_20230727_standard_elasticcloud.json +0 -0
  98. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/results/ElasticCloud/result_20230808_standard_elasticcloud.json +0 -0
  99. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/results/Milvus/result_20230727_standard_milvus.json +0 -0
  100. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/results/Milvus/result_20230808_standard_milvus.json +0 -0
  101. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/results/PgVector/result_20230727_standard_pgvector.json +0 -0
  102. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/results/PgVector/result_20230808_standard_pgvector.json +0 -0
  103. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/results/Pinecone/result_20230727_standard_pinecone.json +0 -0
  104. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/results/Pinecone/result_20230808_standard_pinecone.json +0 -0
  105. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/results/QdrantCloud/result_20230727_standard_qdrantcloud.json +0 -0
  106. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/results/QdrantCloud/result_20230808_standard_qdrantcloud.json +0 -0
  107. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/results/WeaviateCloud/result_20230727_standard_weaviatecloud.json +0 -0
  108. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/results/WeaviateCloud/result_20230808_standard_weaviatecloud.json +0 -0
  109. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/results/ZillizCloud/result_20230727_standard_zillizcloud.json +0 -0
  110. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/results/ZillizCloud/result_20230808_standard_zillizcloud.json +0 -0
  111. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/results/ZillizCloud/result_20240105_standard_202401_zillizcloud.json +0 -0
  112. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/results/dbPrices.json +0 -0
  113. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/results/getLeaderboardData.py +0 -0
  114. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench/results/leaderboard.json +0 -0
  115. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench.egg-info/SOURCES.txt +0 -0
  116. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench.egg-info/dependency_links.txt +0 -0
  117. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench.egg-info/entry_points.txt +0 -0
  118. {vectordb_bench-0.0.8 → vectordb_bench-0.0.10}/vectordb_bench.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vectordb-bench
3
- Version: 0.0.8
3
+ Version: 0.0.10
4
4
  Summary: VectorDBBench is not just an offering of benchmark results for mainstream vector databases and cloud services, it's your go-to tool for the ultimate performance and cost-effectiveness comparison. Designed with ease-of-use in mind, VectorDBBench is devised to help users, even non-professionals, reproduce results or test new systems, making the hunt for the optimal choice amongst a plethora of cloud services and open-source vector databases a breeze.
5
5
  Author-email: XuanYang-cn <xuan.yang@zilliz.com>
6
6
  Project-URL: repository, https://github.com/zilliztech/VectorDBBench
@@ -12,7 +12,7 @@ Description-Content-Type: text/markdown
12
12
  License-File: LICENSE
13
13
  Requires-Dist: pytz
14
14
  Requires-Dist: streamlit-autorefresh
15
- Requires-Dist: streamlit>=1.23.0
15
+ Requires-Dist: streamlit!=1.34.0
16
16
  Requires-Dist: streamlit_extras
17
17
  Requires-Dist: tqdm
18
18
  Requires-Dist: s3fs
@@ -39,6 +39,7 @@ Requires-Dist: sqlalchemy; extra == "all"
39
39
  Requires-Dist: redis; extra == "all"
40
40
  Requires-Dist: chromadb; extra == "all"
41
41
  Requires-Dist: psycopg2; extra == "all"
42
+ Requires-Dist: psycopg; extra == "all"
42
43
  Provides-Extra: qdrant
43
44
  Requires-Dist: qdrant-client; extra == "qdrant"
44
45
  Provides-Extra: pinecone
@@ -49,7 +50,7 @@ Provides-Extra: elastic
49
50
  Requires-Dist: elasticsearch; extra == "elastic"
50
51
  Provides-Extra: pgvector
51
52
  Requires-Dist: pgvector; extra == "pgvector"
52
- Requires-Dist: psycopg2; extra == "pgvector"
53
+ Requires-Dist: psycopg; extra == "pgvector"
53
54
  Provides-Extra: pgvecto-rs
54
55
  Requires-Dist: psycopg2; extra == "pgvecto-rs"
55
56
  Provides-Extra: redis
@@ -26,7 +26,7 @@ classifiers = [
26
26
  dependencies = [
27
27
  "pytz",
28
28
  "streamlit-autorefresh",
29
- "streamlit>=1.23.0",
29
+ "streamlit!=1.34.0",
30
30
  "streamlit_extras",
31
31
  "tqdm",
32
32
  "s3fs",
@@ -59,13 +59,14 @@ all = [
59
59
  "redis",
60
60
  "chromadb",
61
61
  "psycopg2",
62
+ "psycopg",
62
63
  ]
63
64
 
64
65
  qdrant = [ "qdrant-client" ]
65
66
  pinecone = [ "pinecone-client" ]
66
67
  weaviate = [ "weaviate-client" ]
67
68
  elastic = [ "elasticsearch" ]
68
- pgvector = [ "pgvector", "psycopg2" ]
69
+ pgvector = [ "pgvector", "psycopg" ]
69
70
  pgvecto_rs = [ "psycopg2" ]
70
71
  redis = [ "redis" ]
71
72
  chromadb = [ "chromadb" ]
@@ -32,10 +32,10 @@ class config:
32
32
  LOAD_TIMEOUT_1536D_500K = 2.5 * 3600 # 2.5h
33
33
  LOAD_TIMEOUT_1536D_5M = 25 * 3600 # 25h
34
34
 
35
- OPTIMIZE_TIMEOUT_DEFAULT = 15 * 60 # 15min
36
- OPTIMIZE_TIMEOUT_768D_1M = 15 * 60 # 15min
37
- OPTIMIZE_TIMEOUT_768D_10M = 2.5 * 3600 # 2.5h
38
- OPTIMIZE_TIMEOUT_768D_100M = 25 * 3600 # 1.04d
35
+ OPTIMIZE_TIMEOUT_DEFAULT = 30 * 60 # 30min
36
+ OPTIMIZE_TIMEOUT_768D_1M = 30 * 60 # 30min
37
+ OPTIMIZE_TIMEOUT_768D_10M = 5 * 3600 # 5h
38
+ OPTIMIZE_TIMEOUT_768D_100M = 50 * 3600 # 50h
39
39
 
40
40
 
41
41
  OPTIMIZE_TIMEOUT_1536D_500K = 15 * 60 # 15min
@@ -20,6 +20,7 @@ class IndexType(str, Enum):
20
20
  Flat = "FLAT"
21
21
  AUTOINDEX = "AUTOINDEX"
22
22
  ES_HNSW = "hnsw"
23
+ ES_IVFFlat = "ivfflat"
23
24
  GPU_IVF_FLAT = "GPU_IVF_FLAT"
24
25
  GPU_IVF_PQ = "GPU_IVF_PQ"
25
26
  GPU_CAGRA = "GPU_CAGRA"
@@ -14,13 +14,17 @@ class MilvusIndexConfig(BaseModel):
14
14
 
15
15
  index: IndexType
16
16
  metric_type: MetricType | None = None
17
+
18
+ @property
19
+ def is_gpu_index(self) -> bool:
20
+ return self.index in [IndexType.GPU_CAGRA, IndexType.GPU_IVF_FLAT, IndexType.GPU_IVF_PQ]
17
21
 
18
22
  def parse_metric(self) -> str:
19
23
  if not self.metric_type:
20
24
  return ""
21
25
 
22
- # if self.metric_type == MetricType.COSINE:
23
- # return MetricType.L2.value
26
+ if self.is_gpu_index and self.metric_type == MetricType.COSINE:
27
+ return MetricType.L2.value
24
28
  return self.metric_type.value
25
29
 
26
30
 
@@ -8,7 +8,7 @@ from typing import Iterable
8
8
  from pymilvus import Collection, utility
9
9
  from pymilvus import CollectionSchema, DataType, FieldSchema, MilvusException
10
10
 
11
- from ..api import VectorDB, IndexType
11
+ from ..api import VectorDB
12
12
  from .config import MilvusIndexConfig
13
13
 
14
14
 
@@ -89,6 +89,7 @@ class Milvus(VectorDB):
89
89
  connections.disconnect("default")
90
90
 
91
91
  def _optimize(self):
92
+ self._post_insert()
92
93
  log.info(f"{self.name} optimizing before search")
93
94
  try:
94
95
  self.col.load()
@@ -116,9 +117,9 @@ class Milvus(VectorDB):
116
117
  time.sleep(5)
117
118
 
118
119
  wait_index()
119
-
120
+
120
121
  # Skip compaction if use GPU indexType
121
- if self.case_config.index in [IndexType.GPU_CAGRA, IndexType.GPU_IVF_FLAT, IndexType.GPU_IVF_PQ]:
122
+ if self.case_config.is_gpu_index:
122
123
  log.debug("skip compaction for gpu index type.")
123
124
  else :
124
125
  self.col.compact()
@@ -156,6 +157,10 @@ class Milvus(VectorDB):
156
157
 
157
158
  def need_normalize_cosine(self) -> bool:
158
159
  """Wheather this database need to normalize dataset to support COSINE"""
160
+ if self.case_config.is_gpu_index:
161
+ log.info(f"current gpu_index only supports IP / L2, cosine dataset need normalize.")
162
+ return True
163
+
159
164
  return False
160
165
 
161
166
  def insert_embeddings(
@@ -179,8 +184,6 @@ class Milvus(VectorDB):
179
184
  ]
180
185
  res = self.col.insert(insert_data)
181
186
  insert_count += len(res.primary_keys)
182
- if kwargs.get("last_batch"):
183
- self._post_insert()
184
187
  except MilvusException as e:
185
188
  log.info(f"Failed to insert data: {e}")
186
189
  return (insert_count, e)
@@ -0,0 +1,215 @@
1
+ from abc import abstractmethod
2
+ from typing import Any, Mapping, Optional, Sequence, TypedDict
3
+ from pydantic import BaseModel, SecretStr
4
+ from typing_extensions import LiteralString
5
+ from ..api import DBCaseConfig, DBConfig, IndexType, MetricType
6
+
7
+ POSTGRE_URL_PLACEHOLDER = "postgresql://%s:%s@%s/%s"
8
+
9
+
10
+ class PgVectorConfigDict(TypedDict):
11
+ """These keys will be directly used as kwargs in psycopg connection string,
12
+ so the names must match exactly psycopg API"""
13
+
14
+ user: str
15
+ password: str
16
+ host: str
17
+ port: int
18
+ dbname: str
19
+
20
+
21
+ class PgVectorConfig(DBConfig):
22
+ user_name: SecretStr = SecretStr("postgres")
23
+ password: SecretStr
24
+ host: str = "localhost"
25
+ port: int = 5432
26
+ db_name: str
27
+
28
+ def to_dict(self) -> PgVectorConfigDict:
29
+ user_str = self.user_name.get_secret_value()
30
+ pwd_str = self.password.get_secret_value()
31
+ return {
32
+ "host": self.host,
33
+ "port": self.port,
34
+ "dbname": self.db_name,
35
+ "user": user_str,
36
+ "password": pwd_str,
37
+ }
38
+
39
+
40
+ class PgVectorIndexParam(TypedDict):
41
+ metric: str
42
+ index_type: str
43
+ index_creation_with_options: Sequence[dict[str, Any]]
44
+ maintenance_work_mem: Optional[str]
45
+ max_parallel_workers: Optional[int]
46
+
47
+
48
+ class PgVectorSearchParam(TypedDict):
49
+ metric_fun_op: LiteralString
50
+
51
+
52
+ class PgVectorSessionCommands(TypedDict):
53
+ session_options: Sequence[dict[str, Any]]
54
+
55
+
56
+ class PgVectorIndexConfig(BaseModel, DBCaseConfig):
57
+ metric_type: MetricType | None = None
58
+ create_index_before_load: bool = False
59
+ create_index_after_load: bool = True
60
+
61
+ def parse_metric(self) -> str:
62
+ if self.metric_type == MetricType.L2:
63
+ return "vector_l2_ops"
64
+ elif self.metric_type == MetricType.IP:
65
+ return "vector_ip_ops"
66
+ return "vector_cosine_ops"
67
+
68
+ def parse_metric_fun_op(self) -> LiteralString:
69
+ if self.metric_type == MetricType.L2:
70
+ return "<->"
71
+ elif self.metric_type == MetricType.IP:
72
+ return "<#>"
73
+ return "<=>"
74
+
75
+ def parse_metric_fun_str(self) -> str:
76
+ if self.metric_type == MetricType.L2:
77
+ return "l2_distance"
78
+ elif self.metric_type == MetricType.IP:
79
+ return "max_inner_product"
80
+ return "cosine_distance"
81
+
82
+ @abstractmethod
83
+ def index_param(self) -> PgVectorIndexParam:
84
+ ...
85
+
86
+ @abstractmethod
87
+ def search_param(self) -> PgVectorSearchParam:
88
+ ...
89
+
90
+ @abstractmethod
91
+ def session_param(self) -> PgVectorSessionCommands:
92
+ ...
93
+
94
+ @staticmethod
95
+ def _optionally_build_with_options(with_options: Mapping[str, Any]) -> Sequence[dict[str, Any]]:
96
+ """Walk through mappings, creating a List of {key1 = value} pairs. That will be used to build a where clause"""
97
+ options = []
98
+ for option_name, value in with_options.items():
99
+ if value is not None:
100
+ options.append(
101
+ {
102
+ "option_name": option_name,
103
+ "val": str(value),
104
+ }
105
+ )
106
+ return options
107
+
108
+ @staticmethod
109
+ def _optionally_build_set_options(
110
+ set_mapping: Mapping[str, Any]
111
+ ) -> Sequence[dict[str, Any]]:
112
+ """Walk through options, creating 'SET 'key1 = "value1";' commands"""
113
+ session_options = []
114
+ for setting_name, value in set_mapping.items():
115
+ if value:
116
+ session_options.append(
117
+ {"parameter": {
118
+ "setting_name": setting_name,
119
+ "val": str(value),
120
+ },
121
+ }
122
+ )
123
+ return session_options
124
+
125
+
126
+ class PgVectorIVFFlatConfig(PgVectorIndexConfig):
127
+ """
128
+ An IVFFlat index divides vectors into lists, and then searches a subset of those lists that are
129
+ closest to the query vector. It has faster build times and uses less memory than HNSW,
130
+ but has lower query performance (in terms of speed-recall tradeoff).
131
+
132
+ Three keys to achieving good recall are:
133
+
134
+ Create the index after the table has some data
135
+ Choose an appropriate number of lists - a good place to start is rows / 1000 for up to 1M rows and sqrt(rows) for
136
+ over 1M rows.
137
+ When querying, specify an appropriate number of probes (higher is better for recall, lower is better for speed) -
138
+ a good place to start is sqrt(lists)
139
+ """
140
+
141
+ lists: int | None
142
+ probes: int | None
143
+ index: IndexType = IndexType.ES_IVFFlat
144
+ maintenance_work_mem: Optional[str] = None
145
+ max_parallel_workers: Optional[int] = None
146
+
147
+ def index_param(self) -> PgVectorIndexParam:
148
+ index_parameters = {"lists": self.lists}
149
+ return {
150
+ "metric": self.parse_metric(),
151
+ "index_type": self.index.value,
152
+ "index_creation_with_options": self._optionally_build_with_options(
153
+ index_parameters
154
+ ),
155
+ "maintenance_work_mem": self.maintenance_work_mem,
156
+ "max_parallel_workers": self.max_parallel_workers,
157
+ }
158
+
159
+ def search_param(self) -> PgVectorSearchParam:
160
+ return {
161
+ "metric_fun_op": self.parse_metric_fun_op(),
162
+ }
163
+
164
+ def session_param(self) -> PgVectorSessionCommands:
165
+ session_parameters = {"ivfflat.probes": self.probes}
166
+ return {
167
+ "session_options": self._optionally_build_set_options(session_parameters)
168
+ }
169
+
170
+
171
+ class PgVectorHNSWConfig(PgVectorIndexConfig):
172
+ """
173
+ An HNSW index creates a multilayer graph. It has better query performance than IVFFlat (in terms of
174
+ speed-recall tradeoff), but has slower build times and uses more memory. Also, an index can be
175
+ created without any data in the table since there isn't a training step like IVFFlat.
176
+ """
177
+
178
+ m: int | None # DETAIL: Valid values are between "2" and "100".
179
+ ef_construction: (
180
+ int | None
181
+ ) # ef_construction must be greater than or equal to 2 * m
182
+ ef_search: int | None
183
+ index: IndexType = IndexType.ES_HNSW
184
+ maintenance_work_mem: Optional[str] = None
185
+ max_parallel_workers: Optional[int] = None
186
+
187
+ def index_param(self) -> PgVectorIndexParam:
188
+ index_parameters = {"m": self.m, "ef_construction": self.ef_construction}
189
+ return {
190
+ "metric": self.parse_metric(),
191
+ "index_type": self.index.value,
192
+ "index_creation_with_options": self._optionally_build_with_options(
193
+ index_parameters
194
+ ),
195
+ "maintenance_work_mem": self.maintenance_work_mem,
196
+ "max_parallel_workers": self.max_parallel_workers,
197
+ }
198
+
199
+ def search_param(self) -> PgVectorSearchParam:
200
+ return {
201
+ "metric_fun_op": self.parse_metric_fun_op(),
202
+ }
203
+
204
+ def session_param(self) -> PgVectorSessionCommands:
205
+ session_parameters = {"hnsw.ef_search": self.ef_search}
206
+ return {
207
+ "session_options": self._optionally_build_set_options(session_parameters)
208
+ }
209
+
210
+
211
+ _pgvector_case_config = {
212
+ IndexType.HNSW: PgVectorHNSWConfig,
213
+ IndexType.ES_HNSW: PgVectorHNSWConfig,
214
+ IndexType.IVFFlat: PgVectorIVFFlatConfig,
215
+ }