如何用PHP编写CouchDB已删除文档及版本的自动清理脚本
嘿,我来帮你搞定这个CouchDB清理已删除文档的问题!结合你的需求,我会一步步教你构建视图、获取数据,以及创建批量清理的POST请求,处理每月10万级别的删除记录完全没问题。
CouchDB中被删除的文档会以「墓碑」形式保留,带有_deleted: true字段。我们可以创建一个专用视图来快速筛选出这些文档:
首先,向你的数据库发送PUT请求,创建一个设计文档(比如ID为_design/deleted_docs):
PUT /your-db/_design/deleted_docs Content-Type: application/json
请求体里的视图逻辑如下,map函数会筛选出所有标记为删除的文档,并输出它们的ID和当前版本:
{ "views": { "all_deleted": { "map": "function(doc) { if (doc._deleted === true) { emit(doc._id, { _rev: doc._rev }); } }" } } }
创建完成后,你可以通过以下GET请求查询所有已删除文档:
GET /your-db/_design/deleted_docs/_view/all_deleted?include_docs=false&limit=1000
limit=1000是为了分页处理(毕竟10万条数据不能一次性拉取),后续可以用skip或者startkey/endkey来翻页- 如果需要更多文档细节,把
include_docs改成true
如果你需要清理文档的所有历史版本(而不只是当前的墓碑版本),接下来要对每个已删除文档调用_revs_info接口,获取它的所有修订记录:
发送GET请求:
GET /your-db/{doc-id}/_revs_info
返回的结果会包含该文档所有修订版本的状态(available表示版本仍存在,deleted表示已被删除):
{ "revs_info": [ { "rev": "3-abc123", "status": "available" }, { "rev": "2-def456", "status": "available" }, { "rev": "1-ghi789", "status": "deleted" } ] }
我们只需要收集status为available的rev值,这些是需要清理的目标。
_bulk_docs) CouchDB的_bulk_docs接口支持批量操作,非常适合处理大量删除请求。我们需要构建包含所有待删除版本的请求体:
请求的基本信息:
POST /your-db/_bulk_docs Content-Type: application/json
请求体格式如下,每个条目需要指定文档ID、修订版本,并标记_deleted: true:
{ "docs": [ { "_id": "doc-id-1", "_rev": "3-abc123", "_deleted": true }, { "_id": "doc-id-1", "_rev": "2-def456", "_deleted": true }, { "_id": "doc-id-2", "_rev": "1-jkl012", "_deleted": true } // 更多条目... ] }
注意事项:
- 批量大小建议控制在1000条以内,避免请求过大导致超时或服务器压力过高
- 脚本里要处理响应结果,检查是否有操作失败的条目(比如版本冲突),可以记录日志或重试
把上面的步骤串起来,你的脚本逻辑大概是这样:
- 循环分页查询视图,获取所有已删除文档的ID
- 对每个文档ID,调用
_revs_info获取所有可用修订版本 - 收集所有待删除的
_id+_rev组合,分批存入数组 - 每攒够一批(比如1000条),就发送
_bulk_docs请求 - 处理响应,记录成功/失败的条目,确保所有目标都被清理
最后,清理完成后可以在低峰期调用POST /your-db/_compact来压缩数据库,释放磁盘空间——这个操作比较耗资源,记得避开业务高峰!
内容的提问来源于stack exchange,提问作者Trevor

