维护不同的模式版本
您的应用程序的模式要求可能会随时间而变化。例如,当新服务可用时,您可能需要向文档中添加新字段。MongoDB 的灵活数据模型意味着您可以在整个集合中使用非统一的文档结构,并且可以保留较旧的文档结构,同时与更新后的模式一起使用。
模式版本化模式 允许您在同一个集合中拥有不同版本的 schema,从而在需求发生变化时避免大规模的模式迁移。
关于此任务
如果你的文档中存在出现在不同级别的字段,模式版本化模式可能会影响你的索引。例如,如果你在多个文档中,将同一个字段同时存储为顶层字段和嵌入字段,你可能需要多个索引来支持对该字段的查询。
开始之前
以下示例中,一个在线商店使用一个集合来跟踪客户联系信息。最初,该集合只包含家庭和工作电话号码。随着时间的推移,新的联系方式被添加,一些较旧的联系方式不再需要。
插入示例文档
db.contacts.insertOne( { _id: 1, name: "Taylor", home: "209-555-7788", work: "503-555-0110" } )
步骤
以下过程设置了集合的初始模式版本,然后插入一个具有不同模式的新文档。
1
下一步操作
在实现Schema Versioning模式后,您需要修改应用程序查询和更新数据的方式。
查询集合
由于“contacts”集合中存在两个不同的模式,您的查询必须检查根据文档的模式版本所有可能的位置以查找字段值。
以下查询基于客户的work
号码进行搜索。查询检查了work
字段的所有可能位置
db.contacts.find( { $or: [ { work: "503-555-0110" }, { "contactInfo.work": "503-555-0110" } ] } )
输出
{ _id: 1, name: 'Taylor', home: '209-555-7788', work: '503-555-0110', schemaVersion: 1 }
在集合中更新文档
类似于插入数据,当您更新集合时,您的应用程序必须检查要更新的字段的所有可能位置。当您更新数据时,您可以使用schemaVersion
字段来确定要更新的字段。
要更新具有_id: 2
的用户的work
电话号码,运行此命令
db.contacts.updateOne( { _id: 2 }, [ { $set: { "work": { $cond: { if: { $eq: [ "$schemaVersion", 1 ] }, then: "999-999-9999", else: null } }, "contactInfo.work": { $cond: { if: { $eq: [ "$schemaVersion", 2 ] }, then: "999-999-9999", else: null } } } } ] )
在上一个示例中
如果匹配的文档的
schemaVersion
是1
,则将work
字段设置为更新值。如果匹配的文档的
schemaVersion
是2
,则将contactInfo.work
字段设置为更新值。