Docs 菜单
Docs 主页
/
MongoDB Shell

编写脚本

在此页面上

  • 兼容性
  • 执行 JavaScript 文件
  • 从 mongosh 内部执行脚本
  • 从命令行执行脚本
  • 使用身份验证从命令行执行脚本
  • 出错时终止脚本
  • 从配置文件执行代码
  • 执行 JavaScript 代码
  • 执行 MongoDB 代码
  • 执行 JavaScript 和 MongoDB 代码
  • 打开新连接
  • 连接到本地 MongoDB 实例
  • 连接到 Atlas 部署
  • 连接到执行访问控制的 MongoDB 实例
  • 使用 connect() 连接到 MongoDB 实例
  • 连接注意事项

可以为 MongoDB Shell 写入脚本,以修改 MongoDB 中的数据或执行管理操作。您可能还希望将脚本打包成 代码片段,以便于分发和管理。

本教程将介绍如何配合使用 MongoDB Shell 和 JavaScript 以访问 MongoDB。

您可以为以下环境中托管的部署编写 MongoDB Shell 的脚本:

  • MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务

  • MongoDB Enterprise:基于订阅、自行管理的 MongoDB 版本

  • MongoDB Community:source-available、免费使用且可自行管理的 MongoDB 版本

要了解有关在 MongoDB Atlas 托管的部署中使用 MongoDB Shell 的更多信息,请参阅通过 mongosh 连接

您可以使用 load() 方法从 MongoDB Shell 中执行 .js文件。

load() 方法接受相对路径和绝对路径。如果 MongoDB Shell 的当前工作目录是 /data/db ,并且 connect-and-insert.js 位于/data/db/scripts 目录中,则 MongoDB Shell 中的以下调用是等效的:

load( "scripts/connect-and-insert.js" )
load( "/data/db/scripts/connect-and-insert.js" )

以下示例创建并执行以下脚本:

  • 连接到在默认端口上运行的本地实例。

  • 连接到 myDatabase 数据库。

  • 使用示例文档填充 movies 集合。

  1. 创建名为 connect-and-insert.js 的文件,内容如下:

    db = connect( 'mongodb://localhost/myDatabase' );
    db.movies.insertMany( [
    {
    title: 'Titanic',
    year: 1997,
    genres: [ 'Drama', 'Romance' ]
    },
    {
    title: 'Spirited Away',
    year: 2001,
    genres: [ 'Animation', 'Adventure', 'Family' ]
    },
    {
    title: 'Casablanca',
    genres: [ 'Drama', 'Romance', 'War' ]
    }
    ] )
  2. 要加载并执行 connect-and-insert.js 文件,请使用 mongosh 连接到部署并运行以下命令:

    load( "connect-and-insert.js" )
  3. 要确认文件加载正确,请使用 myDatabase 集合并查询 movies 集合。

    use myDatabase
    db.movies.find()

注意

load() 方法没有搜索路径。如果目标脚本不在当前工作目录或指定的完整路径中,MongoDB Shell 将无法访问该文件。

您可以使用 mongosh 从命令行执行脚本,而无需进入 mongosh 控制台。

要指定文件名,请使用 --file-f 参数指定文件名。除 --file-f 参数外,你可能还需要指定连接信息。

提示

如果向 mongosh 传递文件名而不使用参数标志,则在有其他命令行参数的情况下,连接可能会失败。

要传递文件名,请始终使用 --file-f

以下示例将展示如何创建脚本并在命令行运行它。

  1. 复制此脚本并保存为 loadMovies.js

    db = connect( 'mongodb://localhost/films' );
    db.movies.insertMany( [
    {
    title: 'Titanic',
    year: 1997,
    genres: [ 'Drama', 'Romance' ]
    },
    {
    title: 'Spirited Away',
    year: 2001,
    genres: [ 'Animation', 'Adventure', 'Family' ]
    },
    {
    title: 'Casablanca',
    genres: [ 'Drama', 'Romance', 'War' ]
    }
    ] )

    提示

    验证突出显示的行中的连接字符串。如果 MongoDB 实例未在 localhost:27017 上运行,则必须编辑连接字符串。

    例如,以下连接字符串连接到 localhost 端口 27500

    db = connect( 'mongodb://localhost:27500/films' );
  2. 复制此脚本并保存为 queryMovies.js

    db = connect( 'mongodb://localhost/films' );
    printjson( db.movies.find( {} ) );
  3. 从命令行运行脚本。

    mongosh --file loadMovies.js --file queryMovies.js
  4. 验证输出。

    Loading file: loadMovies.js
    Loading file: queryMovies.js
    [
    {
    _id: ObjectId("616f1b8092dbee425b661117"),
    title: 'Titanic',
    year: 1997,
    genres: [ 'Drama', 'Romance' ]
    },
    {
    _id: ObjectId("616f1b8092dbee425b661118"),
    title: 'Spirited Away',
    year: 2001,
    genres: [ 'Animation', 'Adventure', 'Family' ]
    },
    {
    _id: ObjectId("616f1b8092dbee425b661119"),
    title: 'Casablanca',
    genres: [ 'Drama', 'Romance', 'War' ]
    }
    ]

    db.collection.find() 命令的输出显示 movies 集合已更新。

    提示

    要使输出可见,请使用 printjson() 调用 db.collection.find()

    printjson( db.movies.find( {} ) ) ;

要针对需要身份验证的远程 mongod 实例执行脚本,除了文件名外,还要指定连接和身份验证的详细信息。

例如:

mongosh --host 172.17.0.3 --port 27500 --username filmFan --password superSecret --file loadMovies.js

你还可以指定选项的缩写形式:

mongosh --host 172.17.0.3 --port 27500 -u filmFan -p superSecret -f loadMovies.js

提示

bashzsh 等 Shell 中,如果你以空格开始命令,则该命令不会保存在命令历史记录中。这样可以最大限度地减少在命令行上输入密码时的泄露风险。

如果引发异常或出现意外结果,终止运行的脚本通常是非常有用的。通过在脚本中的特定位置退出,可以防止执行不必要的代码和出现潜在的意外结果。

要终止脚本,您可以调用 exit(<code>) 方法,其中 <code> 是用户指定的任何值。

最佳实践是将代码包装在 try - catch 中,并在 catch 区块中调用 exit 方法。 同样,要检查查询或任何命令的结果,您可以添加 if - else 声明,并在结果不符合预期时调用 exit 方法。

启动时,mongosh 会检查 HOME 目录中是否有名为 .mongoshrc.js 的 JavaScript 文件。如果找到此文件,mongosh 会在首次显示提示之前读取 .mongoshrc.js 的内容。

提示

另请参阅:

要更新 mongosh 提示以显示行号,请将以下代码添加到 <your-home-directory>/.mongoshrc.js

let cmdCount = 1;
prompt = function() {
return (cmdCount++) + "> ";
}

提示将如下所示:

1> show collections
2> use test
3>

要创建 mongosh 客户端何时连接到数据库的日志,请将以下代码添加到 <your-home-directory>/.mongoshrc.js

db.clientConnections.insertOne( { connectTime: ISODate() } )

每次连接到数据库时,MongoDB 服务器都会向 clientConnections 集合添加类似下面这样的文档。

{
_id: ObjectId("61d4bbf0fa4c85f53418070f"),
connectTime: ISODate("2022-01-04T21:28:16.367Z")
}

当前数据库名称是默认 mongosh 提示的一部分。要重新格式化提示以显示数据库和主机名,请使用如下函数:

{
const hostnameSymbol = Symbol('hostname');
prompt = () => {
if (!db[hostnameSymbol])
db[hostnameSymbol] = db.serverStatus().host;
return `${db.getName()}@${db[hostnameSymbol]}> `;
};
}

提示将如下所示:

admin@centos0722:27502>

从 MongoDB Shell 或 JavaScript 文件中,您可以使用 Mongo() 方法实例化数据库连接:

new Mongo()
new Mongo(<host>)
new Mongo(<host:port>)

注意

MongoDB Shell 不支持使用 Mongo() 方法的 ClientSideFieldLevelEncryptionOptions 文档。

考虑在默认端口上的本地主机上运行的 MongoDB 实例。

如下示例:

  • 实例化与实例的新连接,并且

  • 使用 Mongo.getDB() 方法将全局 db 变量设置为 myDatabase

conn = Mongo();
db = conn.getDB("myDatabase");

要连接到 MongoDB Atlas 中托管的部署,请使用 Atlas 连接字符串运行 mongosh 命令。例如:

mongosh "mongodb+srv://YOUR_CLUSTER_NAME.YOUR_HASH.mongodb.net/" --apiVersion YOUR_API_VERSION --username YOUR_USERNAME

在建立了与部署的连接之后,您可以直接从 MongoDB Shell 实例化数据库连接。示例如下:

  • 使用 db.getMongo() 方法实例化与当前部署的连接。

  • 使用 Mongo.getDB() 方法将全局 db 变量设置为 myDatabase

conn = db.getMongo()
db = conn.getDB("myDatabase");

如要连接到执行访问控制的 MongoDB 实例,您必须在连接字符串中包含凭证。

以下命令连接到 MongoDB 实例:

  • 在默认端口上运行 localhost,并且

  • 使用 SCRAM 加密。

conn = Mongo("mongodb://<username>:<password>@localhost:27017/<authDB>");

注意

MongoDB Shell 会从命令历史记录日志中删除档案。

你还可以使用 connect()方法连接到 MongoDB 实例。

以下命令:

  • 使用非默认端口 27020 连接到在 localhost 上运行的 MongoDB 实例,并且

  • 设置全局 db 变量。

db = connect("localhost:27020/myDatabase");

在您编写脚本时,请考虑可移植性和操作环境。

如果脚本中包含连接详情:

  • 您无需在命令行中指定连接信息。

  • 你应该使用 --nodb 参数。

假设有一个在 localhost:27500 上运行的 mongod 实例。

以下脚本会打印用户数量。复制代码并将其另存为 getUserCount.js

db = connect( "localhost:27500/admin" );˘
printjson( db.system.users.countDocuments() );

运行 getUserCount.js

mongosh --nodb --file getUserCount.js
  • mongosh 默认为端口 27170。

  • mongod 正在使用端口 27500 运行。

  • --nodb 参数指示 mongosh 在不首先连接到 mongod 实例的情况下运行脚本。

突出显示的行是正确的,但是没有 --nodbgetUserCount.js 将无法运行,因为 mongosh 无法连接到本地实例。使用 --nodb 时,mongosh 运行 getUserCount.js 并使用突出显示的信息进行连接。

在脚本中指定连接信息很方便,但这也会降低脚本的可移植性。getUserCount.js 脚本必须更新才能在远程实例或在不同端口上运行的实例上运行。

为提高可移植性,请使用 db.getSiblingDB() 并在命令行中指定连接信息。

以下脚本比 getUserCount.js 更具可移植性,因为它没有特定的连接详情。复制代码并将其另存为 portableGetUserCount.js

db = db.getSiblingDB( "admin" );
printjson( db.system.users.countDocuments() );

要运行 portableGetUserCount.js,请在命令行中指定主机和端口:

mongosh --host 172.17.0.3 --port 27500 --file portableGetUserCount.js

要在不同主机或端口上运行 portableGetUserCount.js,请在命令行中更改连接详情。与 getUserCount.js不同,你无需编辑脚本即可运行 portableGetUserCount.js

后退

客户端字段级加密 (Client-Side Field Level Encryption)