ITADN
Automattic/mongoose
README.md
以下内容由 AI 翻译,如有问题请点此提交 issue 反馈

Mongoose

Mongoose 是一个 MongoDB 对象建模工具,旨在异步环境中运行。Mongoose 支持 Node.jsDeno(alpha)。

Build Status NPM version Deno version Deno popularity

npm

文档

官方文档网站是 mongoosejs.com

Mongoose 9.0.0 于 2025 年 11 月 21 日发布。您可以在 我们文档网站上查看 9.0.0 中的向后不兼容更改 以获取更多详细信息。

支持

插件

请访问 插件搜索网站 查看社区提供的数百个相关模块。接下来,从 文档这篇博客文章 中学习如何编写自己的插件。

贡献者

始终欢迎 Pull requests!请基于 master 分支创建 pull request,并遵循 贡献指南

如果您的 pull request 包含文档更改,请不要 修改任何 .html 文件。.html 文件是编译后的代码,因此请在 docs/*.puglib/*.jstest/docs/*.js 中进行更改。

查看全部 400 多位 贡献者

安装

首先安装 Node.jsMongoDB,然后使用您首选的包管理器安装 mongoose 包:

使用 npm

npm install mongoose

使用 pnpm

pnpm add mongoose

使用 Yarn

yarn add mongoose

使用 Bun

bun add mongoose

Mongoose 6.8.0 还包含对 Deno 的 alpha 支持。

导入

// Using Node.js `require()`
const mongoose = require('mongoose');

// Using ES6 imports
import mongoose from 'mongoose';

或者,如下使用 Deno 的 createRequire() 以支持 CommonJS

import { createRequire } from 'https://deno.land/std@0.177.0/node/module.ts';
const require = createRequire(import.meta.url);

const mongoose = require('mongoose');

mongoose.connect('mongodb://127.0.0.1:27017/test')
  .then(() => console.log('Connected!'));

然后你可以使用以下命令运行上述脚本。

deno run --allow-net --allow-read --allow-sys --allow-env mongoose-test.js

Mongoose Studio

Mongoose Studio 是一款由 Mongoose 团队开发的免费、完全开源的基于浏览器的 MongoDB GUI,专为已使用 Mongoose 的应用而设计。从 npm 安装 @mongoosejs/studio 并将其作为 Express 中间件与您的应用一起运行,或将其部署到 Vercel 或 Netlify,以浏览和编辑文档,使用现有的模型和模式进行带自动补全的查询,构建仪表板,可视化和编辑 GeoJSON,并使用 AI 辅助的 MongoDB 工作流,而无需将数据迁移到托管的第三方工作区或共享原始 MongoDB 连接字符串。

Mongoose for Enterprise

作为 Tidelift Subscription 的一部分提供

mongoose 的维护者以及数千个其他包的维护者正在与 Tidelift 合作,为您用于构建应用程序的开源依赖项提供商业支持和维护。在支付您实际使用的依赖项维护者的同时,节省时间、降低风险并改善代码健康状况。了解更多。

概述

连接到 MongoDB

首先,我们需要定义一个连接。如果您的应用只使用一个数据库,您应该使用 mongoose.connect。如果需要创建额外的连接,请使用 mongoose.createConnection

connectcreateConnection 都接受一个 mongodb:// URI,或者参数 host, database, port, options

await mongoose.connect('mongodb://127.0.0.1/my_database');

连接成功后,会在 Connection 实例上触发 open 事件。如果你使用的是 mongoose.connect,则 Connectionmongoose.connection。否则,mongoose.createConnection 的返回值是一个 Connection

注意: 如果本地连接失败,请尝试使用 127.0.0.1 代替 localhost。有时,当本地主机名被更改时可能会出现一些问题。

重要! Mongoose 会缓冲所有命令,直到它连接到数据库。这意味着你不必等到它连接到 MongoDB 才能定义模型、运行查询等。

定义模型

模型通过 Schema 接口定义。

const Schema = mongoose.Schema;
const ObjectId = Schema.ObjectId;

const BlogPost = new Schema({
  author: ObjectId,
  title: String,
  body: String,
  date: Date
});

除了定义文档的结构和所存储的数据类型外,Schema 还负责定义以下内容:

以下示例展示了其中一些功能:

const Comment = new Schema({
  name: { type: String, default: 'hahaha' },
  age: { type: Number, min: 18, index: true },
  bio: { type: String, match: /[a-z]/ },
  date: { type: Date, default: Date.now },
  buff: Buffer
});

// a setter
Comment.path('name').set(function(v) {
  return capitalize(v);
});

// middleware
Comment.pre('save', function(next) {
  notify(this.get('email'));
  next();
});

访问模型

一旦我们通过 mongoose.model('ModelName', mySchema) 定义了一个模型,我们就可以通过同一个函数访问它

const MyModel = mongoose.model('ModelName');

或者一次性全部完成

const MyModel = mongoose.model('ModelName', mySchema);

第一个参数是你的模型所对应的集合的单数名称。Mongoose 会自动查找你的模型名称的复数形式。 例如,如果你使用

const MyModel = mongoose.model('Ticket', mySchema);

然后 MyModel 将使用 tickets 集合,而不是 ticket 集合。更多详情请参阅 model docs

一旦我们有了模型,就可以实例化它并保存:

const instance = new MyModel();
instance.my.key = 'hello';
await instance.save();

或者我们可以从同一集合中查找文档

await MyModel.find({});

你也可以 findOnefindByIdupdate 等。

const instance = await MyModel.findOne({ /* ... */ });
console.log(instance.my.key); // 'hello'

有关更多详细信息,请参阅文档

重要! 如果你使用 mongoose.createConnection() 打开了一个单独的连接,但试图通过 mongoose.model('ModelName') 访问模型,它将无法按预期工作,因为它未连接到活动的数据库连接。在这种情况下,请通过你创建的连接访问你的模型:

const conn = mongoose.createConnection('your connection string');
const MyModel = conn.model('ModelName', schema);
const m = new MyModel();
await m.save(); // works

vs

const conn = mongoose.createConnection('your connection string');
const MyModel = mongoose.model('ModelName', schema);
const m = new MyModel();
await m.save(); // does not work b/c the default connection object was never connected

嵌入式文档

在第一个示例代码片段中,我们在 Schema 中定义了一个键,其形式如下:

comments: [Comment]

其中 Comment 是我们创建的 Schema。这意味着创建嵌入式文档非常简单:

// retrieve my model
const BlogPost = mongoose.model('BlogPost');

// create a blog post
const post = new BlogPost();

// create a comment
post.comments.push({ title: 'My comment' });

await post.save();

删除它们也是如此:

const post = await BlogPost.findById(myId);
post.comments[0].deleteOne();
await post.save();

嵌入式文档享有与您的模型完全相同的功能。默认值、验证器、中间件。

中间件

请参阅 docs 页面。

拦截和修改方法参数

您可以通过中间件拦截方法参数。

例如,这将允许您每当有人将您文档中的某个路径 set 为新值时,广播关于您文档的变更:

schema.pre('set', function(next, path, val, typel) {
  // `this` is the current Document
  this.emit('set', path, val);

  // Pass control to the next pre
  next();
});

此外,你可以修改传入的 method 参数,使得后续中间件看到这些参数的不同值。为此,只需将新值传递给 next

schema.pre(method, function firstPre(next, methodArg1, methodArg2) {
  // Mutate methodArg1
  next('altered-' + methodArg1.toString(), methodArg2);
});

// pre declaration is chainable
schema.pre(method, function secondPre(next, methodArg1, methodArg2) {
  console.log(methodArg1);
  // => 'altered-originalValOfMethodArg1'

  console.log(methodArg2);
  // => 'originalValOfMethodArg2'

  // Passing no arguments to `next` automatically passes along the current argument values
  // i.e., the following `next()` is equivalent to `next(methodArg1, methodArg2)`
  // and also equivalent to, with the example method arg
  // values, `next('altered-originalValOfMethodArg1', 'originalValOfMethodArg2')`
  next();
});

Schema 陷阱

type 在 Schema 中使用时,在 Mongoose 内部具有特殊含义。如果您的 Schema 需要将其作为嵌套属性使用 type,则必须使用对象表示法:

new Schema({
  broken: { type: Boolean },
  asset: {
    name: String,
    type: String // uh oh, it broke. asset will be interpreted as String
  }
});

new Schema({
  works: { type: Boolean },
  asset: {
    name: String,
    type: { type: String } // works. asset is an object with a type property
  }
});

驱动程序访问

Mongoose 构建于 官方 MongoDB Node.js 驱动程序 之上。每个 mongoose 模型都保留对 原生 MongoDB 驱动程序集合 的引用。可以使用 YourModel.collection 访问集合对象。然而,直接使用集合对象会绕过所有 mongoose 功能,包括钩子、验证等。一个 值得注意的例外是,YourModel.collection 仍然会缓冲 命令。因此,YourModel.collection.find() 返回游标。

API 文档

Mongoose API 文档,使用 doxacquit 生成。

相关项目

MongoDB 运行器

非官方 CLI

数据填充

Express 会话存储

许可证

Copyright (c) 2010 LearnBoost <dev@learnboost.com>

特此授予任何获得本软件及相关文档文件(“软件”)副本的人, 免费地、无限制地处理软件的权利,包括但不限于使用、复制、修改、合并、发布、 分发、再许可和/或销售软件副本的权利,并允许向其提供软件的人这样做,但须 遵守以下条件:

上述版权声明和本许可声明应包含在软件的所有副本或重要部分中。

软件按“原样”提供,不提供任何形式的保证, 无论是明示的还是默示的,包括但不限于对 适销性、特定用途适用性和非侵权性的保证。 在任何情况下,作者或版权持有人均不对任何 索赔、损害或其他责任负责,无论是基于合同、 侵权或其他行为,均源于或与 软件或软件的使用或其他交易有关。