django-vectorstore-indexed-model
可插拔多后端向量数据库的Django数据模型应用。
安装
pip install django-vectorstore-indexed-model
依赖说明
- 数据模型对于向量数据库的操作深度依赖
openai-simple-vectorstore。该库支持redis-search、milvus、pgvector、elasticsearch、sqlite-vec等多种后端引擎。相关配置详见该项目文档。 - 依赖版本要求:
openai-simple-vectorstore>=0.3.2,因底层自该版本起要求 Python>=3.10,本包同步要求 Python>=3.10。 - 本包读取配置依赖
django-environment-settings(同时支持环境变量与 Django settings),已作为运行时依赖自动安装;示例 app 另需django-model-helper(见requirements.txt的开发依赖)。 - 后端引擎通过环境变量
OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB(别名:VECTOR_DB、VECTOR_DB_TYPE、OPENAI_SIMPLE_VECTORSTORE_BACKEND)选择,默认值为redis。支持redis/milvus/milvus-lite/pgvector/elasticsearch/sqlite-vec/qdrant。 - 索引名归一化:
openai-simple-vectorstore0.3.1 起所有后端都禁止索引名包含:(:被保留作 uid 的<index_name>:<page_id>分隔符)。因此写入 / 删除时索引名会按后端规则自动归一化:所有后端将:替换为_,milvus系列与qdrant额外做完整归一化(仅保留[A-Za-z0-9_])。检索时也需使用归一化后的索引名(可用django_vectorstore_indexed_model.models.normalize_backend_index_name(backend, index_name)计算)。
使用
1. 配置后端引擎
通过环境变量指定向量数据库后端,示例(启动服务前设置):
# 指定后端引擎(默认 redis)
export OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=redis # redis-search(默认)
# export OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=milvus # milvus
# export OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=pgvector # pgvector
# export OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=elasticsearch
# export OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB=sqlite-vec
# 各后端连接配置(以 redis 为例)
export OPENAI_SIMPLE_VECTORSTORE_REDIS_STACK_URL="redis://127.0.0.1:6379"
多后端并行写入
当业务数据(文档、QA 等)发生变更触发索引更新时,可同时向多个后端引擎推送索引。通过环境变量 OPENAI_SIMPLE_VECTORSTORE_VECTOR_DBS(逗号分隔,别名 VECTOR_DBS)指定:
# 同时写入 redis-search 与 milvus 两个后端
export OPENAI_SIMPLE_VECTORSTORE_VECTOR_DBS="redis,milvus"
- 未配置多后端时,退化为单一后端(由
OPENAI_SIMPLE_VECTORSTORE_VECTOR_DB或其别名决定,默认redis)。 - 多后端模式下,
upsert_index/delete_index会把同一份数据一并写入 / 删除到每个后端(按后端顺序逐个执行)。 - uid 记录:单后端时
vectorstore_uids保持为扁平列表["idx:page"];多后端时按后端分组为{"redis": ["idx:page"], "milvus": ["idx:page"]}。
索引默认名称可通过环境变量 VECTORSTORE_INDEX_NAME 配置(默认 default):
export VECTORSTORE_INDEX_NAME=my_index
2. 定义数据模型
继承 WithVectorStoreIndex(抽象基类),并结合模型自身的启用/删除状态字段实现索引开关。
app/models.py
from typing import List
from django.db import models
from django_vectorstore_indexed_model.models import WithVectorStoreIndex
from django_model_helper.models import WithEnabledStatusFields
from django_model_helper.models import WithDeletedStatusFields
class QA(WithEnabledStatusFields, WithDeletedStatusFields, WithVectorStoreIndex):
kb = models.CharField(max_length=64)
question = models.CharField(max_length=128)
answer = models.TextField()
def get_enable_vectorstore_index_flag(self) -> bool:
"""判断是否需要创建索引(返回 True 建索引,False 删除索引)。"""
if not self.enabled:
return False
if self.deleted:
return False
return True
def get_vectorstore_index_names(self):
# 返回该记录需要建立的向量库索引名列表;
# 返回单个元素的 list 表示单索引,返回多个元素表示在多个索引(库)中同时建立。
return [self.kb]
def get_vectorstore_index_contents(self) -> List[str]:
# 向量数据库有索引长度的限制,长文档需要分片;
# 这里返回分片后的内容列表,每一片会作为一条独立向量写入。
return [f"问题:{self.question}\n参考答案:{self.answer}"]
3. 触发索引(建 / 删 / 更新)
update_vectorstore_index 会根据 get_enable_vectorstore_index_flag 自动决定写入还是删除:
qa = QA(kb="kb-001", question="你是谁?", answer="我是你的机器人助理!")
qa.save()
# 触发索引:写入向量并记录返回的 uid
qa.update_vectorstore_index(save=True)
# uid 记录:
# 单后端:扁平列表 ['kb-001:<page_id>', ...]
# 多后端:{backend: [uids]},例如 {'redis': ['kb-001:<page_id>'], 'milvus': [...]}
print(qa.vectorstore_uids)
print(qa.vectorstore_updated) # True:索引成功
4. 检索
使用工厂 create_vector_store() 获取与配置一致的向量库实例(无需关心后端),配合 Pydantic schema 读取结构化结果:
from openai_simple_vectorstore import create_vector_store
from django_vectorstore_indexed_model.schemas import Document
# 单后端:直接获取与配置一致的实例
vs = create_vector_store()
# 检索并重排
docs = vs.similarity_search_and_rerank(
"你是谁",
index_name="kb-001",
document_schema=Document,
)
for doc in docs:
print(doc.content, doc.id, doc.app_label, doc.model_name)
# 多后端:遍历每个后端的实例分别检索
for backend, vs in qa.get_vectorstore_instances():
docs = vs.similarity_search_and_rerank(
"你是谁",
index_name="kb-001",
document_schema=Document,
)
print(backend, docs)
注意:检索的入口仍是引擎(
create_vector_store()/get_vectorstore_instances())。update_vectorstore_index只是把索引写入配置的所有后端;要查询某个后端,直接对该后端实例调用检索方法即可。
注意:索引名会被自动归一化(所有后端)。
openai-simple-vectorstore0.3.1 起:被保留作 uid 分隔符而禁止出现在索引名中,因此写入 / 删除时:
- 所有后端:
:统一替换为_(如faq:kb-uuid→faq_kb-uuid)。milvus系列与qdrant:额外做完整归一化,只保留[A-Za-z0-9_](如faq:kb-uuid→faq_kb_uuid;连字符、点号也替换为_,首字符为数字时前置_)。写入、删除、检索走同一归一化逻辑,同一后端内一致;但检索时必须使用归一化后的索引名。可用
normalize_backend_index_name(backend, index_name)计算,或尽量在get_vectorstore_index_names()中直接使用只含[A-Za-z0-9_-]的索引名(如qa_kb-001)。多后端混用时,同一逻辑索引名在 redis 与 milvus 上可能不同,请按后端分别取用。
按需读取 / 删除时,建议按后端路由(uid 归属各自的后端):
# 单后端:直接对企业主后端实例操作
vs = qa.get_vectorstore_instance()
# 多后端:每个后端的 uid 用各自对应的接口读取 / 删除
for backend, vs in qa.get_vectorstore_instances():
uids = qa.vectorstore_uids.get(backend, []) if isinstance(
qa.vectorstore_uids, dict
) else qa.vectorstore_uids
# 按 uid 读取单条元数据(含嵌入向量)
for uid in uids:
item = vs.get_item(uid)
print(backend, item)
# 删除该后端上的这些 uid
vs.delete_many(uids)
# 清空某个索引(示例:redis 后端)
vs.flush("kb-001")
如需按业务字段过滤,可自定义继承 Document 的 schema 并填充 metadata:
from typing import Optional
from django_vectorstore_indexed_model.schemas import Document
class QASchema(Document):
type: Optional[str] = None
kb: Optional[str] = None
自定义过滤字段
哪些自定义元数据字段可以过滤,由业务侧白名单式声明(默认全部不可过滤):
- 在模型上覆写
get_vectorstore_filterable_fields(),返回可过滤字段名列表。 - 声明的字段会被当作索引 tag 参与过滤;未声明的自定义元数据字段一律序列化为 blob 存储、不可过滤(过滤未声明字段会报错)。
class QA(WithVectorStoreIndex, models.Model):
...
def get_vectorstore_filterable_fields(self):
return ["type"] # 仅 type 这一业务字段可过滤
def get_vectorstore_index_metadata(self):
return {
"app_label": self._meta.app_label,
"model_name": self._meta.model_name,
"id": self.id,
"type": self.get_type(),
}
声明后即可在检索时按该字段过滤:
vs = qa.get_vectorstore_instance()
docs = vs.similarity_search_and_rerank(
"你是谁",
index_name="kb-001",
document_schema=QASchema,
filters={"type": "faq"}, # 仅命中 type=faq 的数据
)
说明:
filterable_metadata_fields会透传给create_vector_store(),对单后端get_vectorstore_instance()与多后端get_vectorstore_instances()均生效。内置的kb_id/doc_id/page_id/category四个字段始终可过滤,无需声明。
声明更丰富的字段类型(推荐)
get_vectorstore_filterable_fields() 只支持 tag(字符串等值)。若需要多值命中(tag_multi)、数值区间(numeric)或全文(text)等能力,请覆写 get_vectorstore_declared_fields(),返回底层 IndexField 列表。优先级高于 get_vectorstore_filterable_fields()(一旦返回非空,后者被忽略):
from openai_simple_vectorstore import IndexField
from django_vectorstore_indexed_model.models import WithVectorStoreIndex
class QA(WithVectorStoreIndex, models.Model):
...
def get_vectorstore_declared_fields(self):
return [
IndexField(name="type", type="tag"), # 字符串等值
IndexField(name="tags", type="tag_multi"), # 多值集合命中
IndexField(name="score", type="numeric"), # 数值,支持 op="range"
]
def get_vectorstore_index_metadata(self):
return {
"app_label": self._meta.app_label,
"model_name": self._meta.model_name,
"id": self.id,
"type": self.get_type(),
"tags": self.get_tags(), # list
"score": self.get_score(), # number
}
检索时即可使用统一的 Filter(数值区间用 op="range"):
from openai_simple_vectorstore import Filter
from django_vectorstore_indexed_model.schemas import Document
vs = qa.get_vectorstore_instance()
docs = vs.similarity_search_and_rerank(
"你是谁",
index_name="kb-001",
document_schema=Document,
filters=[
Filter(field="type", values=["faq"]),
Filter(field="score", values=[7, 10], op="range"), # 7 <= score <= 10
],
)
其它可选写的钩子:
get_vectorstore_create_options()→dict:透传给create_vector_store()的额外参数(如redis_timeout/milvus_timeout/embeddings_llm/embeddings_dims等),默认{}。declared_fields/filterable_metadata_fields由基类统一注入,无需在此返回。
索引生命周期管理
底层自 0.3.1 起把「索引创建 / schema 检查 / 补建 / 重建」与「写入」解耦为显式 API,WithVectorStoreIndex 已按模型涉及的索引名(自动归一化)封装好对应方法:
# 幂等预建 / 补建本记录涉及的所有索引(不写入数据)
qa.create_vectorstore_index()
# 查看各索引的归一化 schema(IndexSchemaInfo)
for backend, indexes in qa.describe_vectorstore_index().items():
for index_name, info in indexes.items():
print(backend, index_name, info.exists, [f.name for f in info.fields])
# 检查各索引声明字段中缺失的原生过滤索引(只读)
for backend, indexes in qa.check_vectorstore_index_fields().items():
for index_name, status in indexes.items():
if status: # 存在待补建字段
print(backend, index_name, status.missing_names)
# 补建缺失的原生过滤索引(幂等)
qa.build_vectorstore_index_fields()
# 检测并重建漂移索引(破坏性:会清空该索引数据)
qa.rebuild_vectorstore_index(force=False) # 仅当检测到 schema 漂移时才重建
这些方法会遍历
get_vectorstore_instances()返回的所有后端,逐个处理get_vectorstore_index_names()中的每个索引。create_vectorstore_index()返回{后端名: [归一化索引名, ...]},describe_vectorstore_index()/check_vectorstore_index_fields()/build_vectorstore_index_fields()/rebuild_vectorstore_index()返回{后端名: {索引名: 结果}}。索引名与写入 / 删除走同一套归一化逻辑。
索引管理命令
除在模型上调用外,也可用管理命令对所有继承 WithVectorStoreIndex 的具体模型批量管理索引:
python manage.py vectorstore_index list # 列出模型与索引名
python manage.py vectorstore_index info # 输出后端 / 索引详情(支持 --format json / --output)
python manage.py vectorstore_index check # 检查存在性、schema 与字段(只读)
python manage.py vectorstore_index compare # 比对线上 schema 与期望,报告漂移(只读)
python manage.py vectorstore_index create # 创建 / 补建索引(幂等,别名 init)
python manage.py vectorstore_index build-fields # 补建后端原生过滤索引(幂等)
python manage.py vectorstore_index delete # 删除 / 清空索引(破坏性,别名 drop / flush)
python manage.py vectorstore_index rebuild # 删除并重建索引(破坏性,别名 reset)
不带
action运行(python manage.py vectorstore_index)会打印动作与选项说明;--help查看完整帮助,各动作也支持python manage.py vectorstore_index <action> --help。
常用参数:
| 参数 | 说明 |
|---|---|
--app APP_LABEL |
仅处理指定 app(可重复)。 |
--model MODEL_NAME |
仅处理指定模型(小写 model_name,可重复)。 |
--index INDEX_NAME |
显式指定逻辑索引名(可重复);给定后不再从数据库记录收集。 |
--backend BACKEND |
仅处理指定后端(可重复),默认全部已配置后端。 |
--live |
list 时连接后端校验索引是否存在及字段(信息更全,但可能较慢 / 依赖后端可用)。 |
--dry-run |
仅打印将要执行的操作,不做任何改动。 |
--noinput / --no-input |
执行 delete / rebuild 等破坏性动作时跳过交互确认。 |
示例:
# 检查 milvus 后端上 QA 模型的全部索引(索引名从数据库记录动态收集)
python manage.py vectorstore_index check --app example --model qa --backend milvus
# 显式对某个索引执行:比对 -> 重建
python manage.py vectorstore_index compare --index faq_kb-001
python manage.py vectorstore_index rebuild --index faq_kb-001 --noinput
未用
--index指定时,命令会遍历相关模型的数据库记录,调用各记录的get_vectorstore_index_names()收集去重后的索引名(大表可能较慢,建议配合--index或--app/--model缩小范围)。索引名同样会按后端规则归一化。
list 默认只展示(无需连接后端)每个模型的记录数、逻辑索引名及归一化后的名称,便于直接用于检索:
example.QA2 (app_label=example, model_name=qa2, 记录数=4)
[redis] default -> default
提示:加 --live 可连接后端显示索引是否存在及字段。
加 --live 则连接后端补充 exists / fields;后端不可用时该项显示 exists=?,不会中断其余输出:
example.QA2 (app_label=example, model_name=qa2, 记录数=4)
[redis] default -> default exists=True fields=['vs_page_id', 'text', 'embedding', 'metadata']
多后端并行写入
配置多个后端后,业务数据变更触发 update_vectorstore_index() 时,会同时把同一份索引写入每个后端引擎:
# 同时写入 redis-search 与 milvus
export OPENAI_SIMPLE_VECTORSTORE_VECTOR_DBS="redis,milvus"
qa = QA(kb="kb-001", question="你是谁?", answer="我是你的机器人助理!")
qa.save()
qa.update_vectorstore_index(save=True)
# 多后端时 vectorstore_uids 按后端分组:
print(qa.vectorstore_uids)
# {'redis': ['kb-001:<page_id>'], 'milvus': ['kb-001:<page_id>']}
删除时,delete_index() 会自动按后端名路由,把各后端的 uid 分别删除:
qa.vectorstore_uids = {"redis": ["kb-001:p"], "milvus": ["kb-001:p"]}
qa.delete_index(save=True) # redis 与 milvus 各自的 uid 都会被删除
说明:
- 多后端配置也可通过 Django settings 提供(
OPENAI_SIMPLE_VECTORSTORE_VECTOR_DBS/VECTOR_DBS)。- 未配置多后端时,一切行为与单一后端完全一致(
vectorstore_uids保持扁平列表),无需改动任何调用代码。- 检索仍需对各后端实例分别调用(见上文「检索」一节)。
合并多模型知识库到同一索引
当不同的模型(如 QA、Doc)返回相同的 get_vectorstore_index_names() 索引名时,
它们的数据会写入同一个向量索引,检索时即可在一次查询中同时命中多个模型。
每条记录自动写入的 metadata 中带有 app_label 与 model_name,据此可区分命中来自哪个模型。
app/models.py —— 两个模型共用同一索引名 kb:
from django.db import models
from django_vectorstore_indexed_model.models import WithVectorStoreIndex
class QA(WithVectorStoreIndex, models.Model):
kb = models.CharField(max_length=64)
question = models.CharField(max_length=128)
answer = models.TextField()
def get_enable_vectorstore_index_flag(self) -> bool:
return True
def get_vectorstore_index_names(self):
return [self.kb] # 与 Doc 共用同一个索引名
def get_vectorstore_index_contents(self):
return [f"问题:{self.question}\n参考答案:{self.answer}"]
class Doc(WithVectorStoreIndex, models.Model):
kb = models.CharField(max_length=64) # 与 QA 相同的知识库字段
title = models.CharField(max_length=128)
body = models.TextField()
def get_enable_vectorstore_index_flag(self) -> bool:
return True
def get_vectorstore_index_names(self):
return [self.kb] # 与 QA 返回同一个索引名
def get_vectorstore_index_contents(self):
return [self.title, self.body] # 文档分片为多段
写入数据并分别建索引:
qa = QA(kb="kb-001", question="如何重置密码?", answer="在设置页点击忘记密码。")
qa.save(); qa.update_vectorstore_index(save=True)
doc = Doc(kb="kb-001", title="用户手册", body="重置密码:进入设置->账户->修改密码。")
doc.save(); doc.update_vectorstore_index(save=True)
一次检索,同时命中两个模型的数据:
from openai_simple_vectorstore import create_vector_store
from django_vectorstore_indexed_model.schemas import Document
vs = create_vector_store()
docs = vs.similarity_search_and_rerank(
"如何修改密码",
index_name="kb-001", # 指向共享索引
document_schema=Document,
)
for doc in docs:
print(
f"[{doc.model_name}] id={doc.id} {doc.content}"
)
# 例如:
# [doc] id=2 重置密码:进入设置->账户->修改密码。
# [qa] id=1 问题:如何重置密码?\n参考答案:在设置页点击忘记密码。
提示:若只需检索某个特定模型的数据,可在 schema 中定义业务字段(如
model_name/type), 检索后按该字段过滤;或为不同模型定制不同的检索路径。
各数据模型使用独立的索引名
若希望不同模型的数据不混用索引,只需让各模型返回不同的 get_vectorstore_index_names() 即可。
这样每个模型维护自己的向量索引(互不干扰),检索时按各自的索引名分别查询。
最常见的做法是在前缀中带上数据模型标识(如 qa_ / doc_),再拼接知识库 id。索引名请避免使用 :(底层保留作 uid 分隔符,会被自动替换为 _)。
app/models.py —— 每个模型使用独立的索引名:
from django.db import models
from django_vectorstore_indexed_model.models import WithVectorStoreIndex
class QA(WithVectorStoreIndex, models.Model):
kb = models.CharField(max_length=64)
question = models.CharField(max_length=128)
answer = models.TextField()
def get_enable_vectorstore_index_flag(self) -> bool:
return True
def get_vectorstore_index_names(self):
# 返回 List[str]:每个元素是一个独立索引名
return [f"qa_{self.kb}"] # 独立索引名:['qa_<kb>']
def get_vectorstore_index_contents(self):
return [f"问题:{self.question}\n参考答案:{self.answer}"]
class Doc(WithVectorStoreIndex, models.Model):
kb = models.CharField(max_length=64)
title = models.CharField(max_length=128)
body = models.TextField()
def get_enable_vectorstore_index_flag(self) -> bool:
return True
# 也可返回 list,让同一模型同时写入多个独立索引
def get_vectorstore_index_names(self):
return [f"doc_{self.kb}", f"doc_title_{self.kb}"]
def get_vectorstore_index_contents(self):
return [self.title, self.body]
分别建索引(各自落到自己的索引中):
qa = QA(kb="kb-001", question="如何重置密码?", answer="在设置页点击忘记密码。")
qa.save(); qa.update_vectorstore_index(save=True)
# qa 写入索引 qa_kb-001
doc = Doc(kb="kb-001", title="用户手册", body="重置密码:进入设置->账户->修改密码。")
doc.save(); doc.update_vectorstore_index(save=True)
# doc 同时写入 doc_kb-001 与 doc_title_kb-001 两个独立索引
按索引名分别检索:
from openai_simple_vectorstore import create_vector_store
from django_vectorstore_indexed_model.schemas import Document
vs = create_vector_store()
# 只在 QA 的索引中查询
qa_docs = vs.similarity_search_and_rerank(
"如何重置密码", index_name="qa_kb-001", document_schema=Document,
)
for d in qa_docs:
print(f"[qa] {d.content}") # 只包含提问/回答
# 只在 Doc 的索引中查询
doc_docs = vs.similarity_search_and_rerank(
"如何重置密码", index_name="doc_kb-001", document_schema=Document,
)
for d in doc_docs:
print(f"[doc] {d.content}") # 只包含文档内容
提示:多个
index_name的取舍——
- 多个模型共用一个索引名 → 一次检索同时命中多模型(上一节)。
- 各模型使用独立索引名 → 检索隔离、互不干扰,也便于按模型单独
flush/清理。 可根据业务对检索范围和隔离性的需求灵活选择。
可以重载的方法
快速解决 contents 与 metadatas 一致情况下的单索引或多重索引问题
get_vectorstore_index_names:返回List[str]类型,每个元素为一个索引名;单元素 list 表示单索引,多元素表示在多索引(库)中同时建立。基类实现统一按 list 处理,返回裸字符串也会被自动归一化为单元素 list。get_vectorstore_index_contents:返回分片后的内容列表(须实现,否则抛出NotImplementedError)。get_vectorstore_index_metadata:返回单条 metadata 字典;默认含app_label、model_name、id。get_vectorstore_index_metadatas(contents=None):默认返回每页一份 metadata 的列表(逐页copy,避免共享同一 dict 引用),content 与 meta 一致时无需重载。get_vectorstore_index_pages:返回VSPage列表,可完全自定义每条写入记录(索引名 / 内容 / 单页元数据 / 定位字段);默认按get_vectorstore_index_names()×get_vectorstore_index_contents()生成,覆写后其索引名须与get_vectorstore_index_names()保持一致。
以上方法默认由抽象基类提供实现,可按需在子类中重载。
其他可重载的钩子
get_enable_vectorstore_index_flag→bool:控制是否启用索引(基类抛出NotImplementedError,须实现)。get_kb_id():知识库标识,默认"default"。get_doc_id():文档标识,默认"default"。get_page_id():分页标识,默认uuid.uuid4();多后端写入时同一批页面(及 page_id)在各后端间复用,保证跨后端 page_id 一致。get_category():分类标识,默认"default"。get_vectorstore_instance(backend=None):返回向量库实例,默认以当前配置的首个后端(get_vectorstore_backends()[0])显式调用openai_simple_vectorstore.create_vector_store(backend, ...),可按需重载;显式backend优先(用于避免多后端列表只配置一项时回退到底层默认后端)。get_vectorstore_filterable_fields():返回本模型可过滤的自定义元数据字段名列表(白名单),默认[];声明后这些字段会作为索引 tag 参与过滤。get_vectorstore_declared_fields():返回底层IndexField列表,支持tag/tag_multi/numeric/text,默认[];非空时优先于get_vectorstore_filterable_fields()。get_vectorstore_create_options():返回透传给create_vector_store()的额外参数(连接 / 超时 / 模型等),默认{}。upsert_index(save=False)/delete_index(save=False):手动写入 / 删除本次记录的索引。create_vectorstore_index()/describe_vectorstore_index()/check_vectorstore_index_fields()/build_vectorstore_index_fields()/rebuild_vectorstore_index(force=True):索引生命周期管理(见上文「索引生命周期管理」)。
版本记录
v0.3.2
- 兼容:适配
openai-simple-vectorstore0.3.2。 依赖提升为>=0.3.2、Python 提升为>=3.10;统一索引名归一化规则(禁止:,milvus / qdrant 额外完整归一化),检索时请使用归一化后的索引名。 - 新增:更丰富的字段类型与过滤。 可声明
tag/tag_multi/numeric/text字段,支持数值区间等过滤,并透传后端连接 / 超时 / 嵌入模型等创建参数。 - 新增:索引生命周期管理。 覆盖建索引、schema 查询、过滤索引检查与补建、漂移检测与重建,既可在模型上调用,也可用
vectorstore_index管理命令批量执行。 - 新增:检索洞察。
vectorstore_search可对指定索引做检索压测与结果洞察,输出耗时、命中数与结果详情。 - 改进:检索结果更易用。
Document自动兼容底层vs_*字段,业务字段均能正确回填,并提供content/embedding/uid/index_name等便捷访问器。 - 性能:检索与导入更快。 检索默认不再取回原始向量,大 k / 高网络延迟下显著提速(需要时用
--include-embedding开启);多页导入改为分组批量写入,实测提速约 1.7x–2.9x。 - 修复:多后端配置与写入更稳健。 修复后端错配、非字符串索引名崩溃、settings 以 list 配置多后端解析错误等问题;写入失败时尽力回滚,重复后端自动去重。
- 修复:示例应用与构建。 修正示例 QA2 索引名不一致并补齐缺失迁移(
makemigrations --check无待生成变更);补齐django-environment-settings运行时依赖并修复 pytest 收集配置。
v0.3.0
- 新增:接入多后端向量数据库,摆脱对单一引擎的绑定。
- 支持通过环境变量切换后端引擎(redis-search / milvus / pgvector / elasticsearch / sqlite-vec 等),默认 redis。
- 底层统一由
create_vector_store()按配置创建实例,业务侧无需感知后端差异。
- 新增:支持同时向多个后端写入索引,便于迁移 / 双写 / 容灾。
- 通过
OPENAI_SIMPLE_VECTORSTORE_VECTOR_DBS指定多个后端,数据变更时同时向每个引擎推送索引。 - 写入的 uid 按后端分组记录,删除时按后端路由。
- 通过
- 新增:支持按业务自定义字段过滤检索。
- 在模型上覆写
get_vectorstore_filterable_fields()白名单声明可过滤的自定义元数据字段。 - 声明的字段作为索引 tag 参与过滤;未声明的自定义字段仅随元数据存储、不可过滤。
- 单后端
get_vectorstore_instance()与多后端get_vectorstore_instances()均生效。
- 在模型上覆写
v0.2.0
- 修正:避免保存数据时触发重复 / 死循环的索引重建。
- 保存时不再自动重建索引。
- 新增:支持按知识库、文档、类型等字段过滤检索。
- 匹配最新的
openai-redis-vectorstore,支持字段知识库、文档、类型过滤。
- 匹配最新的
v0.1.1
- 新增:支持 content 与 meta 各不相同的多重索引场景。
- 添加
WithVectorStoreIndex.get_vectorstore_index_segments以支持 content 与 meta 各不相同的多重索引。
- 添加
- 修复:打包时版本号引用问题。
v0.1.0
- 首发:首个可用版本。
Metadata
Release files for django-vectorstore-indexed-model 0.3.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_vectorstore_indexed_model-0.3.2.tar.gz | 67.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_vectorstore_indexed_model-0.3.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 129.5 kB
Release files / django_vectorstore_indexed_model-0.3.2.tar.gz
| Download URL | django_vectorstore_indexed_model-0.3.2.tar.gz |
|---|---|
| Size | 67.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
990e704e865220a39f96e678c725b75ea6ba91ac19bd70206cb171ec61f5b106
|
|
BLAKE2b-256 checksum How to use checksums |
003a7c18606b820324a9d731cfb5ba83d771c031a96294ee3493519fb35804b6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|
Release files / django_vectorstore_indexed_model-0.3.2-py3-none-any.whl
| Download URL | django_vectorstore_indexed_model-0.3.2-py3-none-any.whl |
|---|---|
| Size | 62.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
61c31a3604311816b4f5bcc8145243775b35b753126deb57bb6d4b873119f0ee
|
|
BLAKE2b-256 checksum How to use checksums |
2fa4d64df07a72e9f6355b7219e7147cd09b30a83d89f6473e0553168870d97e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|