Metadata-Version: 2.4
Name: openai-simple-vectorstore
Version: 0.1.0
Summary: 可扩展的多向量数据库（redis-search / milvus 等），集成embeddings和rerank模型，支持二阶段召回，支持添加和删除等管理功能。
Author: rRR0VrFP
Maintainer: rRR0VrFP
License-Expression: MIT
Project-URL: Homepage, https://gitee.com/rRR0VrFP/openai-simple-vectorstore
Keywords: openai-simple-vectorstore,vectorstore,redis-search,milvus,milvus-lite,pgvector,elasticsearch,sqlite-vec
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: PyYAML
Requires-Dist: httpx
Requires-Dist: pydantic
Requires-Dist: python-environment-settings
Requires-Dist: zenutils
Provides-Extra: redis
Requires-Dist: redis; extra == "redis"
Requires-Dist: redisvl>=0.27.1; extra == "redis"
Provides-Extra: milvus
Requires-Dist: pymilvus>=2.3; extra == "milvus"
Provides-Extra: milvus-lite
Requires-Dist: pymilvus>=2.3; extra == "milvus-lite"
Requires-Dist: milvus-lite; extra == "milvus-lite"
Provides-Extra: pgvector
Requires-Dist: psycopg2-binary; extra == "pgvector"
Provides-Extra: elasticsearch
Requires-Dist: elasticsearch>=8.0; extra == "elasticsearch"
Provides-Extra: sqlite-vec
Requires-Dist: sqlite-vec; extra == "sqlite-vec"
Provides-Extra: all
Requires-Dist: redis; extra == "all"
Requires-Dist: redisvl>=0.27.1; extra == "all"
Requires-Dist: pymilvus>=2.3; extra == "all"
Requires-Dist: milvus-lite; extra == "all"
Requires-Dist: psycopg2-binary; extra == "all"
Requires-Dist: elasticsearch>=8.0; extra == "all"
Requires-Dist: sqlite-vec; extra == "all"
Dynamic: license-file

# openai-simple-vectorstore

可扩展的多向量数据库接入库，内置 **redis-search**、**milvus**、**pgvector**、
**elasticsearch** 与 **sqlite-vec** 等后端，并提供统一的 embeddings / rerank
二阶段召回、插入、删除、刷新等管理接口。

- redis-search 后端与 [openai-redis-vectorstore](https://gitee.com/rRR0VrFP/openai-redis-vectorstore)
  行为 100% 兼容（相同的 uid 规则、relevance score、索引 schema）。
- 通过工厂 + 注册表机制可低成本扩展其它向量数据库后端。

## 安装

作为业务方使用时，从 PyPI 安装本库并选择所需后端：

```bash
# 默认后端（redis-search）
pip3 install openai-simple-vectorstore

# 仅 redis-search 后端
pip3 install "openai-simple-vectorstore[redis]"

# 仅 milvus 后端（依赖 pymilvus）
pip3 install "openai-simple-vectorstore[milvus]"

# 仅 milvus-lite 后端（嵌入式 milvus，无需单独部署，适合本地开发/测试）
pip3 install "openai-simple-vectorstore[milvus-lite]"

# 仅 pgvector 后端（依赖 psycopg2-binary）
pip3 install "openai-simple-vectorstore[pgvector]"

# 仅 elasticsearch 后端
pip3 install "openai-simple-vectorstore[elasticsearch]"

# 仅 sqlite-vec 后端（嵌入式 SQLite，无需单独部署）
pip3 install "openai-simple-vectorstore[sqlite-vec]"

# 全部后端
pip3 install "openai-simple-vectorstore[all]"
```

> 在仓库源码目录内本地开发时使用 `pip3 install -e ".[all]"`；离线安装本库自身依赖时，
> 使用 `pip3 install --no-index --find-links wheelhouse/ -r requirements.txt`。

## 快速开始

### 选择 redis-search 后端（默认）

```python
from openai_simple_vectorstore import create_vector_store

vs = create_vector_store()  # 默认后端由 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB 决定

# 插入
uid = vs.insert("今天天气很好", kb_id="kb1", doc_id="doc1", page_id="p1")

# 二阶段召回（向量检索 + rerank 重排）
docs = vs.similarity_search_and_rerank(
    query="今天天气怎么样",
    index_name="default",
    k=3,
)
for doc in docs:
    print(doc.vs_page_content, doc.vs_embeddings_score, doc.vs_rerank_score)

# 删除 / 刷新
vs.delete(uid)
vs.flush("default")
```

### 选择 milvus 后端

```python
from openai_simple_vectorstore import create_vector_store

vs = create_vector_store(  # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=milvus
    vector_db="milvus"
)
vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
```

### 选择 milvus-lite 后端（嵌入式，本地开发/测试）

milvus-lite 与 milvus 使用相同的 `MilvusClient` API，仅连接方式不同：milvus 通过
`http://host:19530` 连接服务端，milvus-lite 通过本地文件路径启动进程内嵌入式数据库，
无需部署 milvus 服务。

```python
from openai_simple_vectorstore import create_vector_store

vs = create_vector_store(
    vector_db="milvus-lite",  # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=milvus-lite
    milvus_lite_uri="./milvus_lite.db",  # 默认 OPENAI_SIMPLE_VECTORSTORE_MILVUS_LITE_URI
)
vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
```


### 选择 sqlite-vec 后端（嵌入式，本地开发/测试）

sqlite-vec 是 SQLite 的向量搜索扩展，所有数据存在本地文件中，无需单独部署服务。
注意：需要 sqlite3 支持 loadable-extension（多数发行版 CPython 均支持）。

```python
from openai_simple_vectorstore import create_vector_store

vs = create_vector_store(
    vector_db="sqlite-vec",  # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=sqlite-vec
    sqlite_vec_uri="./sqlite_vec.db",  # 默认 OPENAI_SIMPLE_VECTORSTORE_SQLITE_VEC_URI
)
vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
```

### 选择 pgvector 后端（PostgreSQL 扩展）

需要 PostgreSQL 已安装 pgvector 扩展（程序启动时会尝试 ``CREATE EXTENSION IF NOT EXISTS vector``）：

```python
from openai_simple_vectorstore import create_vector_store

vs = create_vector_store(
    vector_db="pgvector",  # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=pgvector
    pgvector_url="postgresql://user:pass@localhost:5432/postgres",  # 默认 OPENAI_SIMPLE_VECTORSTORE_PGVECTOR_URL
)
vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
```

### 选择 elasticsearch 后端

需要 Elasticsearch 8.x（dense_vector + HNSW）：

```python
from openai_simple_vectorstore import create_vector_store

vs = create_vector_store(
    vector_db="elasticsearch",  # 或环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=elasticsearch
    es_url="http://localhost:9200",
)
vs.insert("..." , kb_id="kb1", doc_id="doc1", page_id="p1")
docs = vs.similarity_search_and_rerank(query="...", index_name="default", k=3)
```

### 直接实例化（不依赖全局配置）

```python
from openai_simple_vectorstore import RedisVectorStore
from openai_simple_vectorstore.base import Connection
from openai_simple_vectorstore.utils import YamlSerializer

vs = RedisVectorStore(
    redis_stack_url="redis://localhost:6379/0",
    embeddings_llm=Connection(base_url="http://localhost/v1", api_key="sk-xxx"),
    rerank_llm=Connection(base_url="http://localhost/v1", api_key="sk-xxx"),
    embeddings_model="bge-m3",
    rerank_model="bge-reranker-v2-m3",
    metadata_serializer=YamlSerializer(),
)
```

## 环境变量

| 变量 | 默认值 | 说明 |
| --- | --- | --- |
| `OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB` | `redis` | 后端：`redis` / `redis-search` / `milvus` / `milvus-lite` / `pgvector` / `elasticsearch` / `sqlite-vec` |
| `OPENAI_SIMPLE_VECTORSTORE_REDIS_STACK_URL` | `redis://localhost:6379/0` | redis-stack 地址（redis 后端） |
| `OPENAI_SIMPLE_VECTORSTORE_MILVUS_URI` | `http://localhost:19530` | milvus 地址 |
| `OPENAI_SIMPLE_VECTORSTORE_MILVUS_TOKEN` | 空 | milvus 鉴权 token |
| `OPENAI_SIMPLE_VECTORSTORE_MILVUS_LITE_URI` | `./milvus_lite.db` | milvus-lite 本地数据库文件路径 |
| `OPENAI_SIMPLE_VECTORSTORE_PGVECTOR_URL` | `postgresql://localhost:5432/postgres` | pgvector 连接串（pgvector 后端） |
| `OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_URL` | `http://localhost:9200` | elasticsearch 地址 |
| `OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_API_KEY` | 空 | elasticsearch API key（优先于账号密码） |
| `OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_USERNAME` | 空 | elasticsearch 用户名 |
| `OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_PASSWORD` | 空 | elasticsearch 密码 |
| `OPENAI_SIMPLE_VECTORSTORE_ELASTICSEARCH_VERIFY_CERTS` | `True` | 是否校验证书（自签 HTTPS 集群可设 `false`） |
| `OPENAI_SIMPLE_VECTORSTORE_SQLITE_VEC_URI` | `./sqlite_vec.db` | sqlite-vec 本地数据库文件路径 |
| `OPENAI_BASE_URL` | `http://localhost/v1` | OpenAI 兼容服务基础地址 |
| `OPENAI_API_KEY` | 空 | OpenAI 兼容服务密钥 |
| `OPENAI_EMBEDDINGS_MODEL` | `bge-m3` | embeddings 模型名 |
| `OPENAI_RERANK_MODEL` | `bge-reranker-v2-m3` | rerank 模型名 |

> 兼容 `openai-redis-vectorstore`：`OPENAI_REDIS_VECTORSTORE_REDIS_STACK_URL`、
> `OPENAI_EMBEDDINGS_*`、`OPENAI_RERANK_*`、`OPENAI_BASE_URL`、`OPENAI_API_KEY` 等变量可直接使用。

## 扩展新的向量数据库后端

继承共享抽象基类 `VectorStore` 并实现以下方法，再注册到工厂即可：

1. 实现 `get_cached_vectorstore`（引擎的获取与缓存）
2. 实现 `_search_index`，返回 `[(page_id, distance, item), ...]`
3. 实现 `get_item` / `delete` / `delete_many` / `flush`

```python
from openai_simple_vectorstore.base import VectorStore
from openai_simple_vectorstore.registry import register_vector_store, create_vector_store

class MyStore(VectorStore):
    def get_cached_vectorstore(self, **kwargs): ...
    def _search_index(self, engine, query_embedding, index_name,
                      kb_ids, categories, filter_expression, k): ...
    def get_item(self, uid): ...
    def delete(self, uid): ...
    def delete_many(self, uids): ...
    def flush(self, index_name=None): ...

register_vector_store("mydb", MyStore)
vs = create_vector_store(vector_db="mydb")
```

`base` 会统一处理 embeddings 生成、rerank、过滤、去重、排序、`relevance_score` 与
`Document` 组装，后端只需专注各自的检索实现。

## 概念说明

- **uid**：`<index_name>:<page_id>`，用于唯一定位一条记录。
- **relevance_score**：`1 - distance`，取值 `[0, 1]`，越大越相关。
- **二阶段召回**：`similarity_search_and_rerank` 先用向量检索取 `k * scale` 条候选，
  再经 rerank 重排取前 `k` 条。

## 开发与测试

```bash
python3 -m pytest -q
```

跑 `pytest` 时的覆盖率门槛在 `pytest.ini` 中（`--cov-fail-under=90`）；
`.coveragerc` 的 `fail_under=80` 只作用于单独执行 `coverage report` 的场合。

测试分两类：

- **单元测试**（`test_unit.py` / `test_engines_*.py`）：全部基于内存 fake，离线可跑。
- **真实嵌入式/外部服务集成测试**（`test_engines_integration.py`）：优先使用真实数据库
  跑完整链路（本地 OpenAI 兼容 HTTP stub 提供 embeddings/rerank，覆盖 base 真实 HTTP 路径）：
  - `milvus-lite`：进程内嵌入，直接运行；
  - `sqlite-vec`：需要 sqlite3 支持 loadable-extension，否则自动跳过
    （本机 python.org 构建默认不支持，可用支持扩展的 Homebrew python3 执行）；
  - `pgvector`：外部服务，通过 `OPENAI_SIMPLE_VECTORSTORE_PGVECTOR_URL` 指定连接串，
    连接可达才执行。例如：

    ```bash
    podman run -d --name pgvector-pg17 -p 55432:5432 \
      -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres \
      docker.io/pgvector/pgvector:pg17

    OPENAI_SIMPLE_VECTORSTORE_PGVECTOR_URL='postgresql://postgres:postgres@localhost:55432/postgres' \
      python3 -m pytest test_engines_integration.py -q
    ```

```bash
# 真实嵌入式/外部后端（milvus-lite / sqlite-vec / pgvector，按运行时能力自动启用）
python3 -m pytest test_engines_integration.py -q
```

## 版本记录

### 0.1.0（2026-09-08）

- 首个正式版本：在 redis-search 与 milvus 基础上新增 **pgvector**、**elasticsearch**、
  **sqlite-vec** 三个后端（factory + registry 注册，支持 extras 选择性安装）。
- 统一 embeddings / rerank 二阶段召回、插入 / 删除 / 更新（upsert）/ 查询 / 刷新等接口。
- 新增 kb / category 元数据过滤语义：各引擎在向量候选上按元数据过滤。
- milvus（独立部署）与 milvus-lite 支持同 page_id 更新（upsert）与删除后立即可见。
- elasticsearch 显式声明 kb / doc / category 等 keyword 映射以支持过滤，并自动迁移旧 schema。
- 新增对 pgvector / elasticsearch / sqlite-vec / milvus 真实外部服务的端到端测试
  （`test_engines_integration.py`），覆盖率 96%（阈值 90%）。

## License

[MIT](LICENSE)
