跳到主要内容

MongoDB数据库

本指南讨论了使用Prisma ORM和MongoDB背后的概念,解释了MongoDB和其他数据库提供程序之间的共性和差异,并引导您完成使用Prisma-ORM配置应用程序以与MongoDB集成的过程。

信息

要将Prisma ORM与MongoDB连接,请参阅我们的入门文档.

什么是MongoDB?

MongoDB数据库是存储数据的NoSQL数据库BSON公司format,一种类似JSON的文档格式,用于将数据存储在键值对中。它通常用于JavaScript应用程序开发,因为文档模型很容易映射到应用程序代码中的对象,并且内置了对高可用性和水平缩放的支持。

MongoDB将数据存储在不需要预先定义模式的集合中,就像您需要处理关系数据库中的表一样。每个集合的结构也可以随时间变化。这种灵活性允许快速迭代数据模型,但这确实意味着在使用Prisma ORM处理MongoDB数据库时存在许多差异。

与其他数据库提供商的共性

在MongoDB中使用Prisma ORM的某些方面与在关系数据库中使用Primma ORM时相同。您仍然可以:

需要考虑的差异

MongoDB基于文档的结构和灵活的模式意味着在MongoDB中使用Prisma ORM与在关系数据库中使用它有很多不同之处。您需要注意以下方面的差异:

  • 定义ID:MongoDB文档有一个_身份证字段(通常包含对象ID). Prisma ORM不支持以开头的字段_,因此需要使用@地图属性。有关更多信息,请参阅在MongoDB中定义ID.

  • 迁移现有数据以匹配Prisma模式:在关系数据库中,所有数据都必须与模式匹配。如果在迁移时更改架构中特定字段的类型,则还必须更新所有数据以匹配。相反,MongoDB不强制任何特定的模式,所以在迁移时需要小心。有关更多信息,请参阅如何将旧数据迁移到新模式.

  • 反思与Prisma ORM关系:当您检视现有MongoDB数据库时,您将得到一个没有关系的模式,需要手动添加缺少的关系。有关更多信息,请参阅反思后如何添加缺失关系.

  • 筛选无效的和缺少的字段:MongoDB区分了将字段设置为无效的并且根本不设置它,这在关系数据库中不存在。Prisma ORM目前没有表示这种区别,这意味着您在筛选无效的和缺少的字段。有关更多信息,请参阅如何筛选无效的和缺少的字段

  • 启用复制:Prisma ORM使用MongoDB事务在内部避免对嵌套查询进行部分写入。使用事务时,MongoDB要求启用数据集的复制。为此,您需要配置副本集-这是一组维护相同数据集的MongoDB进程。注意,通过创建一个只有一个节点的副本集,仍然可以使用单个数据库阿特拉斯托管服务,副本集是为您配置的,但如果您在本地运行MongoDB,则需要自己设置副本集。有关更多信息,请参阅MongoDB部署副本集指南.

如何将Prisma ORM与MongoDB结合使用

本节提供了如何执行需要MongoDB特定步骤的任务的说明。

如何迁移现有数据以匹配您的Prisma架构

随着时间的推移迁移数据库是开发周期的重要组成部分。在开发期间,您需要更新Prisma模式(例如,添加新字段),然后更新开发环境数据库中的数据,最后将更新的模式和新数据推送到生产数据库。

信息

在使用MongoDB时,请注意,您的模式和数据库之间的“耦合”是有意设计的,与SQL数据库相比没有那么严格;MongoDB不会强制实施模式,因此您必须验证数据完整性。

更新模式和数据库的这些迭代任务可能会导致模式与数据库中的实际数据不一致。让我们来看一个可能发生这种情况的场景,然后为您和您的团队研究处理这些不一致性的几种策略。

脚本:您需要包括用户的电话号码和电子邮件。您当前拥有以下内容用户您的模型方案.棱镜文件:

棱镜/方案棱镜
模型用户 {
身份证件字符串 @标识 @默认(汽车()) @地图(“_id”) @数据库.对象ID
电子邮件字符串
}

您可以使用许多策略迁移此模式:

  • “按需”更新:使用此策略,您和您的团队已经同意可以根据需要对模式进行更新。然而,为了避免由于数据和模式之间的不一致而导致迁移失败,团队一致认为,添加的任何新字段都明确定义为可选。

    在上面的场景中,您可以添加一个可选的电话号码字段到用户Prisma模式中的模型:

    棱镜/方案棱镜
    模型用户 {
    身份证件字符串 @标识 @默认(汽车()) @地图(“_id”) @数据库.对象ID
    电子邮件字符串
    电话号码字符串?
    }

    然后使用npx棱镜生成命令。接下来,更新您的应用程序以反映新字段,并重新部署您的应用程序。

    作为电话号码字段是可选的,您仍然可以查询尚未定义电话号码的旧用户。当应用程序的用户开始在新字段中输入他们的电话号码时,数据库中的记录将“按需”更新。

    另一个选项是在必填字段中添加默认值,例如:

    棱镜/方案棱镜
    模型用户 {
    身份证件字符串 @标识 @默认(汽车()) @地图(“_id”) @数据库.对象ID
    电子邮件字符串
    电话号码字符串 @默认("000-000-0000")
    }

    然后当你遇到一个失踪电话号码,值将被强制转换为000-000-0000.

  • “无中断更改”更新:此策略建立在第一个策略的基础上,您的团队进一步达成共识,即不重命名或删除字段,只添加新字段,并始终将新字段定义为可选字段。可以通过在CI/CD进程中添加检查来加强此策略,以验证架构中没有向后不兼容的更改。

  • “一次性”更新:此策略类似于关系数据库中的传统迁移,其中所有数据都会更新以反映新模式。在上面的场景中,您将创建一个脚本,为数据库中的所有现有用户添加电话号码字段的值。然后,您可以将字段设置为应用程序中的必填字段,因为模式和数据是一致的。

反思后如何添加缺失关系

自省现有MongoDB数据库后,需要手动添加模型之间的关系。MongoDB没有像在关系数据库中那样通过外键定义关系的概念。然而,如果MongoDB中的集合具有与另一个集合的ID字段匹配的“类似外键”字段,则Prisma ORM将允许您模拟集合之间的关系。

例如,以具有两个集合的MongoDB数据库为例,用户岗位。这些集合中的数据具有以下格式用户ID将用户链接到帖子的字段:

用户集合:

  • _身份证类型为的字段对象ID
  • 电子邮件字段类型为一串

岗位集合:

  • _标识字段类型为对象ID
  • 标题字段类型为一串
  • 用户ID具有以下类型对象ID

关于自省db拉力,这被拉入Prisma模式,如下所示:

棱镜/方案棱镜
模型岗位 {
身份证件字符串 @标识 @默认(汽车()) @地图(“_id”) @数据库.对象ID
标题字符串
用户ID字符串 @数据库.对象ID
}

模型用户 {
身份证件字符串 @标识 @默认(汽车()) @地图(“_id”) @数据库.对象ID
电子邮件字符串
}

这缺少了用户岗位模型。要解决此问题,请手动添加用户字段到岗位带有的模型@关系属性使用用户ID作为领域值,将其链接到用户模型,以及帖子字段到用户模型作为反向关系:

棱镜/方案棱镜
模型岗位 {
身份证件字符串 @标识 @默认(汽车()) @地图(“_id”) @数据库.对象ID
标题字符串
用户ID字符串 @数据库.对象ID
用户用户 @关系(领域: [用户ID], 参考文献: [身份证件])
}

模型用户 {
身份证件字符串 @标识 @默认(汽车()) @地图(“_id”) @数据库.对象ID
电子邮件字符串
帖子岗位[]
}

有关如何在Prisma ORM中使用关系的更多信息,请参见我们的文档.

如何筛选无效的和缺少的字段

了解MongoDB如何区分无效的以及缺少的字段,请考虑用户带有可选的模型名称字段:

模型用户{
id字符串@身份证件@违约(汽车()) @地图(“_id”) @数据库.对象ID
电子邮件字符串
name字符串?
}

首先,尝试使用名称字段显式设置为无效的Prisma ORM将返回名称:null如预期:

常量创建Null= 等待棱镜.用户.创造({
数据: {
电子邮件: 'user1@prisma.io',
名称: 无效的,
},
})
慰问.日志(创建Null)
显示CLI(命令行界面)结果

如果直接检查MongoDB数据库,还将看到一条新记录名称设置为无效的:

{
“_id”: “6242c4af032bc76da250b207”,
“电子邮件”: "user1@prisma.io",
“名称”: 无效的
}

接下来,尝试在不显式设置名称字段:

常量创建Missing= 等待棱镜.用户.创造({
数据: {
电子邮件: 'user2@prisma.io',
},
})
慰问.日志(创建Missing)
显示CLI(命令行界面)结果

Prisma ORM仍然返回名称:null,但如果您直接查看数据库,您将看到该记录没有名称字段定义:

{
“_id”: “6242c4af032bc76da250b208”,
“电子邮件”: "user2@prisma.io"
}

Prisma ORM在这两种情况下都返回相同的结果,因为我们目前没有办法在MongoDB中指定以下字段之间的差异无效的以及根本没有定义的字段-请参阅这个Github问题了解更多信息。

这意味着您当前在筛选无效的和缺少的字段。使用筛选记录名称:null将只返回第一条记录名称显式设置为无效的:

常量查找Null= 等待棱镜.用户.查找许多({
哪里: {
名称: 无效的,
},
})
慰问.日志(查找Null)
显示CLI(命令行界面)结果

这是因为名称:null正在检查相等性,而不存在的字段不等于无效的.

要同时包含缺少的字段,请使用isSet(设置)滤波器要显式搜索以下字段无效的或未设置。这将返回两个记录:

常量查找Null或缺少= 等待棱镜.用户.查找许多({
哪里: {
: [
{
名称: 无效的,
},
{
名称: {
isSet(设置): ,
},
},
],
},
})
慰问.日志(查找Null或缺少)
显示CLI(命令行界面)结果

关于将MongoDB与Prisma ORM结合使用的更多信息

开始将MongoDB与Prisma ORM结合使用的最快方法是参考我们的入门文档:

这些教程将带您了解连接到MongoDB、推动模式更改和使用Prisma Client的过程。

有关更多参考信息,请参阅MongoDB连接器文档.

有关如何设置和管理MongoDB数据库的更多信息,请参阅Prisma数据指南.

例子

要连接到MongoDB服务器,请配置数据源阻止您的Prisma模式:

方案.棱镜
数据源数据库{
供应商= “mongodb”
网址= 环境价值(“数据库URL”)
}

传递给的字段数据源块包括:

  • 供应商:指定数据库数据源连接器。
  • 网址:指定连接URL用于MongoDB服务器。在这种情况下使用了环境变量提供连接URL。
警告

MongoDB数据库连接器使用事务来支持嵌套写入。交易要求一个副本集部署。部署副本集的最简单方法是使用阿特拉斯。可以免费开始。

连接详细信息

连接URL

根据您托管数据库的方式,可以以不同的方式配置MongoDB连接URL。标准配置由以下组件组成:

MongoDB连接URL的结构

基本URL和路径

连接URL的基本URL和路径部分由您的身份验证凭据、主机(以及可选的端口号)和数据库组成。

mongodb://用户名:密码@主机/数据库

以下组件构成基地址数据库的:

姓名占位符描述
用户用户名数据库用户的名称,例如。日本
密码密码数据库用户的密码
主机主机主机蒙古族实例正在运行。如果您正在运行一个分片集群,这将芒戈人实例。这可以是主机名、IP地址或UNIX域套接字。
端口港口运行数据库服务器的端口,例如。1234。如果未提供,则默认27017使用。
数据库数据库要使用的数据库的名称。如果除authSource(授权源)选项,然后authSource(授权源)使用数据库名称。如果连接字符串中的数据库和authSource(授权源)选项,然后默认为管理员

论据

连接URL也可以接受参数。以下示例设置了三个参数:

  • ssl协议连接
  • A类连接超时MS
  • 以及最大池大小
mongodb://用户名:密码@主机/数据库?ssl=true&connectTimeoutMS=5000&maxPoolSize=50

请参阅MongoDB连接字符串文档获取连接字符串参数的完整列表。没有Prisma ORM特定的参数。

使用对象ID

这是_标识包含对象ID:

{
“_id”: { “$oid”: “60d599cb001 ef98000f2cad2” },
“创建时间”: { “$date”: { “$numberLong”: "1624611275577" } },
“电子邮件”: "ella@prisma.io",
“名称”: “艾拉”,
“角色”: “管理员”
}

映射到对象ID在基础数据库中:

  • 必须为类型字符串字节
  • 必须包括@数据库。对象ID属性
  • 可以选择使用@默认值(auto())自动生成有效的对象ID关于文档创建

下面是一个使用字符串:

模型用户 {
身份证件字符串 @标识 @默认(汽车()) @地图(“_id”) @数据库.对象ID
//其他字段
}

下面是另一个使用字节:

模型用户 {
身份证件字节 @标识 @默认(汽车()) @地图(“_id”) @数据库.对象ID
//其他字段
}

另请参见:在MongoDB中定义ID字段

生成对象ID

要生成有效的对象ID(为了测试或手动设置ID字段值),请在应用程序中使用布森包裹。

npm安装--保存bson
进口 {对象ID}  “bson”

常量身份证件= 新的 对象ID()

关系数据库连接器的区别

本节介绍MongoDB连接器与关系数据库的Prisma ORM连接器的不同之处。

不支持Prisma Migrate

目前,没有计划添加对的支持Prisma迁移因为MongoDB项目不依赖内部模式,因此需要使用额外的工具来管理更改。管理@独一无二的索引是通过以下方式实现的数据库推送.

不支持@@标识自动递增()

这个@@标识不支持属性(多个字段的ID),因为MongoDB中的主键始终位于_身份证模型的字段。

这个自动递增()函数(创建递增@标识不支持值),因为自动递增()不适用于对象ID键入_标识MongoDB中有字段。

循环引用和引用操作

如果您的模型中有循环引用,无论是来自自我关系还是模型之间的关系循环,那么您可以使用参照动作,必须设置的引用操作无操作以防止动作的无限循环。

请参见参照动作的特殊规则了解更多详细信息。

副本集配置

MongoDB只允许您在副本集上启动事务。Prisma ORM在内部使用事务以避免对嵌套查询进行部分写入。这意味着我们继承了需要配置副本集的要求。

当您尝试在未配置副本集的部署上使用Prisma ORM的MongoDB连接器时,Prisma OR会显示以下消息错误:此部署不支持事务。错误消息的全文如下:

PrismaClientUnknownRequestError2[PrismaClientUnknow请求错误]:
中的“prisma.post.create()”调用无效
/索引:9:21

6等待棱镜$连接()
7
8//创建第一个帖子
9等待棱镜.post.create(
连接器错误:数据库错误。错误代码:未知,错误消息:此部署不支持事务
在cb(/node_modules/@prisma/client/runtime/index.js:34804:17)
processTicksAndRejections(内部/process/task_queues.js:97:5){
客户端版本:“3.xx.0”
}

要解决此问题,我们建议您将部署更改为配置了副本集的部署。

一个简单的方法是使用MongoDB地图集启动一个具有现成副本集支持的免费实例。

还有一个使用本指南在本地运行副本集的选项:https://docs.mongodb.com/manual/tutorial/convert-standalone-to-replica-set

MongoDB和Prisma模式之间的类型映射

MongoDB连接器映射标量类型来自Prisma ORM数据模型到MongoDB的本机列类型,如下所示:

或者,请参见Prisma架构引用用于按Prisma类型组织的类型映射。

从Prisma ORM到MongoDB的本机类型映射

Prisma ORM公司MongoDB数据库
字符串一串
布尔值布尔
国际整数
BigInt公司长的
浮子双重的
十进制的当前不支持
日期时间时间戳
字节binData(二进制数据)
杰森

当前不受支持的MongoDB类型:

  • 小数128
  • 未定义
  • DB指针
  • 无效的
  • 符号
  • MinKey(最小密钥)
  • MaxKey(最大密钥)
  • 对象
  • Java脚本
  • 带范围的Javascript
  • Regex公司

在自省中从MongoDB到Prisma ORM类型的映射

在自省MongoDB数据库时,Prisma ORM使用相关的标量类型。某些特殊类型还可以获得其他本机类型批注:

MongoDB(类型|别名)Prisma ORM公司支持本机数据库类型属性笔记
对象ID字符串✔️@数据库。对象ID

反思添加本机数据库类型尚不支持作为不受支持领域:

棱镜方案
模型例子 {
身份证件字符串 @身份证 @默认(汽车()) @地图(“_id”) @数据库.对象ID
名称字符串
正则表达式不受支持(“正则表达式”)
}