维护不同的模式版本
应用程序的架构要求可能会随着时间的推移而改变。例如,当新服务可用时,您可能需要向文档中添加新字段。MongoDB 灵活的数据模型意味着您可以在整个集合中使用非统一的文档结构,并且可以在更新架构的同时保留旧的文档结构。
通过模式版本控制模式,您可以在同一个集合中拥有不同版本的模式,从而避免在需求发生变化时进行大规模的模式迁移。
关于此任务
如果字段在文档中的不同级别出现,则模式版本控制模式可能会影响索引。例如,如果将同一字段作为顶级字段和嵌入字段存储到不同的文档中,则可能需要多个索引来支持对相应字段的查询。
开始之前
在以下示例中,一家在线商店使用一个集合来跟踪客户联系信息。起初,该集合仅包含家庭和工作电话号码。随着时间的推移,新的联系方式不断增加,该商店已不再需要一些旧的联系方式。
插入示例文档:
db.contacts.insertOne( { _id: 1, name: "Taylor", home: "209-555-7788", work: "503-555-0110" } )
步骤
以下过程设置集合的初始模式版本,然后插入具有不同模式的新文档。
1
后续步骤
实现 Schema Versioning Pattern 之后,您需要修改应用程序如何查询和更新数据。
查询集合
既然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
字段将设置为更新后的值。