文档菜单
文档首页
/
MongoDB 手册
/ / /

维护不同的模式版本

本页内容

  • 关于此任务
  • 开始之前
  • 步骤
  • 向集合添加 schemaVersion 字段
  • 插入带有更新模式的文档
  • 下一步
  • 查询集合
  • 更新集合中的文档
  • 了解更多

您的应用程序的模式要求可能会随时间而变化。例如,当新服务可用时,您可能需要向文档中添加新字段。MongoDB 的灵活数据模型意味着您可以在整个集合中使用非统一的文档结构,并且可以保留较旧的文档结构,同时与更新后的模式一起使用。

模式版本化模式 允许您在同一个集合中拥有不同版本的 schema,从而在需求发生变化时避免大规模的模式迁移。

如果你的文档中存在出现在不同级别的字段,模式版本化模式可能会影响你的索引。例如,如果你在多个文档中,将同一个字段同时存储为顶层字段和嵌入字段,你可能需要多个索引来支持对该字段的查询。

以下示例中,一个在线商店使用一个集合来跟踪客户联系信息。最初,该集合只包含家庭和工作电话号码。随着时间的推移,新的联系方式被添加,一些较旧的联系方式不再需要。

插入示例文档

db.contacts.insertOne(
{
_id: 1,
name: "Taylor",
home: "209-555-7788",
work: "503-555-0110"
}
)

以下过程设置了集合的初始模式版本,然后插入一个具有不同模式的新文档。

1

为了在集合中区分不同的模式,添加一个schemaVersion字段。

以下命令向具有初始模式的文档添加一个值为1schemaVersion字段

db.contacts.updateMany(
{ },
{
$set: { schemaVersion: 1 }
}
)
2

在更新的模式中,客户可以链接他们的社交媒体账户。插入一个考虑了新要求的文档,其schemaVersion2

db.contacts.insertOne(
{
_id: 2,
schemaVersion: 2,
name: "Cameron",
contactInfo: {
cell: "903-555-1122",
work: "670-555-7878",
instagram: "@camcam9090",
linkedIn: "CameronSmith123"
}
}
)

在实现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
}
}
}
}
]
)

在上一个示例中

  • 如果匹配的文档的schemaVersion1,则将work字段设置为更新值。

  • 如果匹配的文档的schemaVersion2,则将contactInfo.work字段设置为更新值。

  • 保留文档版本的历史记录

  • 模式验证

  • 模式设计过程

返回

保留文档历史