前面介绍了如何新增、修改数据,要从 Chroma 中删除数据,请使用 delete() 方法。
删除数据要谨慎,一旦删除,数据不能恢复。删除数据前,最好将删除的数据导出来备份,然后再进行删除。
方法签名如下:
collection.delete(
ids=None,
where=None,
where_document=None,
limit=None,
)参数说明:
ids:类型为 list[str] | None,表示要删除的文档 id 列表。例如:ids=["id1", "id2"],直接按主键删除指定条目。
where:类型为 dict | None,元数据过滤条件,根据 metadata 字段筛选待删除数据。 采用 Chroma 的查询过滤语法。例如:where={"type": "news"},删除 metadata 里 type 等于 news 的所有记录。 支持操作符:$eq、$gt、$gte、$lt、$lte、$ne、$in、$nin
where_document:类型为 dict | None,文档内容过滤,根据原始文本 document 内容筛选删除。 仅支持 $contains(文本包含子串) 例如:where_document={"$contains":"demo"} 删除document 文本中含有 demo 的记录
limit:类型为 int | None,表示删除数量上限,限制本次最多删除多少条,防止一次性误删大量数据。
注意:
多个条件同时写:逻辑 AND,必须全部满足才会删除
删除是永久删除,无法恢复!建议先使用 collection.get() 用同样条件查询,确认结果再执行 delete 操作。
至少提供其中一种筛选条件:ids / where / where_document,不能全部为空(不允许一键清空全库),否则抛出如下错误,例如:
import chromadb
client = chromadb.EphemeralClient()
collection = client.get_or_create_collection("demo_collection", embedding_function=None)
try:
collection.delete(
ids=None,
where=None,
where_document=None,
limit=None,
)
except Exception as e:
print("delete 不给条件就会被拒(防手滑删库,必须显式指定删哪些):", type(e).__name__, e)运行代码,输出如下:
delete 不给条件就会被拒(防手滑删库,必须显式指定删哪些):
ValueError At least one of ids, where, or where_document must be provided in delete.下面将分别介绍按 ids、where、where_document 进行删除。
这个最好理解,也最为简单,和关系型数据库中的根据主键删除是一样的,用法如下:
col.delete(ids=["d1", "d2"])示例:
import chromadb
client = chromadb.EphemeralClient()
collection = client.get_or_create_collection("demo_collection", embedding_function=None)
# 准备数据
collection.add(
ids=["q1", "q2", "q3", "q4"],
documents=[
"订单付款后多久发货?一般 48 小时内出库",
"如何申请退款?在订单详情页点击申请退款",
"发票怎么开?在个人中心-发票管理里申请电子发票",
"快递丢了怎么办?联系客服补发或全额退款",
],
metadatas=[
{"category": "物流"},
{"category": "售后"},
{"category": "财务"},
{"category": "售后"},
],
)
# 删除数据
collection.delete(
ids=["q1", "q3"], # 指定要删除记录的ID
where=None,
where_document=None,
limit=None,
)
# 查看数据
result = collection.get(limit=100, offset=0, include=["documents", "metadatas"])
ids = result["ids"]
print(f"ids={result["ids"]}")
print(f"documents={result["documents"]}")
print(f"metadatas={result["metadatas"]}")运行示例,输出如下:
ids=['q2', 'q4']
documents=['如何申请退款?在订单详情页点击申请退款', '快递丢了怎么办?联系客服补发或全额退款']
metadatas=[{'category': '售后'}, {'category': '售后'}]从输出可知,id 为 q1 和 q2 的记录被删除了。
即根据记录中的 metadatas 数据,采用过滤的方式进行删除,满足条件则删除,否则不删除。这是不是类似关系型数据库中的 where 条件。
使用方式如下:
import chromadb
client = chromadb.EphemeralClient()
collection = client.get_or_create_collection("demo_collection", embedding_function=None)
# 删除数据
# 1. $eq 等于(简写形式,直接写值等价 $eq)
collection.add(ids=["d1"], embeddings=[[0.1, 0.2, 0.3]], documents=["d1"],
metadatas=[{"category": "临时", "year": 2024}])
collection.delete(where={"category": "临时"})
collection.add(ids=["d2"], embeddings=[[0.1, 0.2, 0.3]], documents=["d2"],
metadatas=[{"category": "临时", "year": 2024}])
collection.delete(where={"category": {"$eq": "临时"}})
# 2. $ne 不等于
collection.add(ids=["d3"], embeddings=[[0.1, 0.2, 0.3]], documents=["d3"],
metadatas=[{"category": "正式", "year": 2024}])
collection.delete(where={"category": {"$ne": "临时"}})
# 3. $gt 大于(仅数字 int/float)
collection.add(ids=["d4"], embeddings=[[0.1, 0.2, 0.3]], documents=["d4"],
metadatas=[{"category": "正式", "year": 2021}])
collection.delete(where={"year": {"$gt": 2020}})
# 4. $gte 大于等于
collection.add(ids=["d5"], embeddings=[[0.1, 0.2, 0.3]], documents=["d5"],
metadatas=[{"category": "正式", "year": 2020}])
collection.delete(where={"year": {"$gte": 2020}})
# 5. $lt 小于
collection.add(ids=["d6"], embeddings=[[0.1, 0.2, 0.3]], documents=["d6"],
metadatas=[{"category": "正式", "year": 2019}])
collection.delete(where={"year": {"$lt": 2020}})
# 6. $lte 小于等于
collection.add(ids=["d7"], embeddings=[[0.1, 0.2, 0.3]], documents=["d7"],
metadatas=[{"category": "正式", "year": 2020}])
collection.delete(where={"year": {"$lte": 2020}})
# 7. $in 在列表内
collection.add(ids=["d8"], embeddings=[[0.1, 0.2, 0.3]], documents=["d8"],
metadatas=[{"category": "测试", "year": 2024}])
collection.delete(where={"category": {"$in": ["临时", "测试", "草稿"]}})
# 8. $nin 不在列表内
collection.add(ids=["d9"], embeddings=[[0.1, 0.2, 0.3]], documents=["d9"],
metadatas=[{"category": "草稿", "year": 2024}])
collection.delete(where={"category": {"$nin": ["正式", "发布"]}})
# 9. 多条件 AND 同时满足:chroma 1.5 不再支持多 key 隐式 AND,必须用显式 $and 包裹
collection.add(ids=["d10"], embeddings=[[0.1, 0.2, 0.3]], documents=["d10"],
metadatas=[{"category": "临时", "year": 2024}])
collection.delete(where={
"$and": [
{"category": "临时"},
{"year": {"$lt": 2025}}
]
})
# 10. 显式 $and 嵌套多条件
collection.add(ids=["d11"], embeddings=[[0.1, 0.2, 0.3]], documents=["d11"],
metadatas=[{"category": "临时", "year": 2023}])
collection.delete(where={
"$and": [
{"category": "临时"},
{"year": {"$gte": 2020}}
]
})
# 11. $or 或条件,满足任意一条即可
collection.add(ids=["d12"], embeddings=[[0.1, 0.2, 0.3]], documents=["d12"],
metadatas=[{"category": "发布", "year": 2017}])
collection.delete(where={
"$or": [
{"category": "临时"},
{"year": {"$lt": 2018}}
]
})
# 查询记录数
print(f"集合总记录数 {collection.count()}")
# 结果:
# 集合总记录数 0该种删除方式是模糊匹配删除,如果文档中包含指定的文本,则删除。否则,不进行删除。用法如下:
import chromadb
client = chromadb.EphemeralClient()
collection = client.get_or_create_collection("demo_collection", embedding_function=None)
# 准备数据
collection.add(
ids=["q1", "q2", "q3", "q4"],
documents=[
"订单付款后多久发货?一般 48 小时内出库",
"如何申请退款?在订单详情页点击申请退款",
"发票怎么开?在个人中心-发票管理里申请电子发票",
"快递丢了怎么办?联系客服补发或全额退款",
],
metadatas=[
{"category": "物流"},
{"category": "售后"},
{"category": "财务"},
{"category": "售后"},
],
)
# 删除数据
collection.delete(
ids=None,
where=None,
where_document={
"$contains": "订单" # 删除内容包含【订单】的记录
},
limit=None,
)
# 查看数据
result = collection.get(limit=100, offset=0, include=["documents", "metadatas"])
ids = result["ids"]
print(f"ids={result["ids"]}")
print(f"documents={result["documents"]}")
print(f"metadatas={result["metadatas"]}")执行完成后,id 为 q1 和 q2 的记录成功被删除:
ids=['q3', 'q4']
documents=['发票怎么开?在个人中心-发票管理里申请电子发票', '快递丢了怎么办?联系客服补发或全额退款']
metadatas=[{'category': '财务'}, {'category': '售后'}]这个参数挺有用,能避免一次误删太多,一是避免在条件写错时错误删除大量数据,二是避免一次删除大量数据,导致程序长时间等待删除动作完成。
示例:
import chromadb
client = chromadb.EphemeralClient()
collection = client.get_or_create_collection("demo_collection", embedding_function=None)
# 准备数据
collection.add(
ids=["q1", "q2", "q3", "q4"],
documents=[
"订单付款后多久发货?一般 48 小时内出库",
"如何申请退款?在订单详情页点击申请退款",
"发票怎么开?在个人中心-发票管理里申请电子发票",
"快递丢了怎么办?联系客服补发或全额退款",
],
metadatas=[
{"category": "物流"},
{"category": "售后"},
{"category": "财务"},
{"category": "售后"},
],
)
# 删除数据
collection.delete(
ids=None,
where=None,
where_document={
"$contains": "订单" # 删除内容包含【订单】的记录
},
limit=1, # 删除限制,仅删除一条匹配记录
)
# 查看数据
result = collection.get(limit=100, offset=0, include=["documents", "metadatas"])
ids = result["ids"]
print(f"ids={result["ids"]}")
print(f"documents={result["documents"]}")
print(f"metadatas={result["metadatas"]}")上面示例插入 4 条数据,包含【订单】字符串的记录有两条,分别是 q1 和 q2,但是仅删除了 q1,被限制一次仅能删除一条数据。最终输出如下:
ids=['q2', 'q3', 'q4']
documents=['如何申请退款?在订单详情页点击申请退款', '发票怎么开?在个人中心-发票管理里申请电子发票', '快递丢了怎么办?联系客服补发或全额退款']
metadatas=[{'category': '售后'}, {'category': '财务'}, {'category': '售后'}]