mongoDB_04

MongoDB_04

Attribution: MongoDB: The Definitive Guide, Third Edition by Shannon Bradshaw, Eoin Brazil, and Kristina Chodorow (O’Reilly). Copyright 2020 Shannon Bradshaw and Eoin Brazil, 978-1-491-95446-1.


Using the MongoDB Shell

This section covers how to use the shell as part of your command-line toolkit, customize it, and use some of its more advanced functionality.

To connect to a mongod on a different machine or port, specify the hostname, port, and database when starting the shell:

$ mongosh mongodb://127.0.0.1:27017/
MongoDB shell version: 7.0.12
connecting to: some-host:mongodb://127.0.0.1:27017/
>

db will now refer to *some-host:30000* ’s myDB database.

Sometimes it is handy to not connect to a mongod at all when starting the mongo shell. If you start the shell with --nodb, it will start up without attempting to connect to anything:

> mongosh --nodb
Current Mongosh Log ID: 66ae66df0774e613dbc4e49a
Using Mongosh:          2.2.12

Once started, you can connect to a mongod at your leisure by running new Mongo("*hostname*"):

> conn = new Mongo("some-host:30000")
connection to some-host:30000
> db = conn.getDB("myDB")
myDB

After these two commands, you can use db normally. You can use these commands to connect to a different database or server at any time.


Tips for Using the Shell

Because mongo is simply a JavaScript shell, you can get a great deal of help for it by simply looking up JavaScript documentation online.

For MongoDB-specific functionality, the shell includes built-in help that can be accessed by typing help:

> help

  Shell Help:

    use                                        Set current database
    show                                       'show databases'/'show dbs': Print a list of all available databases.
                                               'show collections'/'show tables': Print a list of all collections for current database.
                                               'show profile': Prints system.profile information.
                                               'show users': Print a list of all users for current database.
                                               'show roles': Print a list of all roles for current database.
                                               'show log <type>': log for current connection, if type is not set uses 'global'
                                               'show logs': Print all logs.
... ...

Database-level help is provided by db.help() and collection-level help by db.foo.help().

> db.help()

  Database Class:

    getMongo                                   Returns the current database connection
    getName                                    Returns the name of the DB
    getCollectionNames                         Returns an array containing the names of all collections in the current database.
... ...

> db.fooo.help()

  Collection Class:

    aggregate                                  Calculates aggregate values for the data in a collection or a view.
    bulkWrite                                  Performs multiple write operations with controls for order of execution.
    count                                      Returns the count of documents that would match a find() query for the collection or view.    
... ...

Running Scripts with the Shell

In addition to using the shell interactively, you can also pass the shell JavaScript files to execute. Simply pass in your scripts at the command line:

$ mongosh script1.js script2.js script3.js
I am script1.js
I am script2.js
I am script3.js

The mongosh shell will execute each script listed and exit.

If you want to run a script using a connection to a nondefault host/port mongod, specify the address first, then the script(s):

$ mongosh "mongodb://127.0.0.1:27017/foo" script1.js script2.js script3.js

This would execute the three scripts with db set to the foo database on some-host:30000.

You can print to stdout in scripts (as the preceding scripts did) using the print function. This allows you to use the shell as part of a pipeline of commands.

You can also run scripts from within the interactive shell using the load function:

> load("script1.js")
I am script1.js
true

Scripts have access to the db variable (as well as any other global).

However, shell helpers such as use db or show collections do not work from files. There are valid JavaScript equivalents to each of these, as shown in Table.

Helper Equivalent
use video db.getSisterDB("video")
show dbs db.getMongo().getDBs()
show collections db.getCollectionNames()

You can also use scripts to inject variables into the shell.

For example, you could have a script that simply initializes helper functions that you commonly use. It defines a function, connectTo, that connects to the locally running database on the given port and sets db to that connection:

// defineConnectTo.js

/**
 * Connect to a database and set db.
 */
var connectTo = function(port, dbname) {
    if (!port) {
        port = 27017;
    }

    if (!dbname) {
        dbname = "test";
    }

    db = connect("localhost:"+port+"/"+dbname);
    return db;
};

If you load this script in the shell, connectTo is now defined:

test> typeof connectTo
undefined
test> load('defineConnectTo.js')
true
test> typeof connectTo
function

In addition to adding helper functions, you can use scripts to automate common tasks and administrative activities.

By default, the shell will look in the directory that you started the shell in (use pwd to see what directory that is in Windows cmd or PowerShell ).If the script is not in your current directory, you can give the shell a relative or absolute path to it.

For example, if you wanted to put your shell scripts in ~/my-scripts, you could load defineConnectTo.js with load("/home/myUser/my-scripts/defineConnectTo.js"). Note that load cannot resolve ~.


Creating a .mongoshrc.js

If you have frequently loaded scripts, you might want to put them in your .mongorc.js file. This file is run whenever you start up the shell.

// .mongoshrc.js

var compliment = ["attractive", "intelligent", "like Saya"];
var index = Math.floor(Math.random()*3);

print("Hello, you're looking particularly "+compliment[index]+" today!");

You should put the mongoshrc.js file in the /%USERPROFILE%/ (Windows) directory so that when you start mongosh, you’ll see something like:

> mongosh
Current Mongosh Log ID: 66ae758d9edba0e788c4e49a
Connecting to:          mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.2.12
Using MongoDB:          7.0.12
Using Mongosh:          2.2.12
mongosh 2.2.15 is available for download: https://www.mongodb.com/try/download/shell

For mongosh info see: https://docs.mongodb.com/mongodb-shell/

------
   The server generated these startup warnings when booting
   2024-07-27T16:15:36.491+08:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
------

Hello, you're looking particularly like Saya today!
>

More practically, you can use this script to set up any global variables you’d like to use, alias long names to shorter ones, and override built-in functions.

One of the most common uses for .mongorc.js is to remove some of the more “dangerous” shell helpers.

You can override functions like dropDatabase or deleteIndexes with no-ops or undefine them altogether:

var no = function() {
    print("Not on my watch.");
};

// Prevent dropping databases
db.dropDatabase = DB.prototype.dropDatabase = no;

// Prevent dropping collections
DBCollection.prototype.drop = no;

// Prevent dropping an index
DBCollection.prototype.dropIndex = no;

// Prevent dropping indexes
DBCollection.prototype.dropIndexes = no;

Now if you try to call any of these functions, it will simply print an error message. Note that this technique does not protect you against malicious users; it can only help with fat-fingering.

You can disable loading your .mongorc.js by using the --norc option when starting the shell.


Customizing Your Prompt

The default shell prompt can be overridden by setting the prompt variable to either a string or a function.

For example, if you are running a query that takes minutes to complete, you may want to have a prompt that displays the current time so you can see when the last operation finished:

prompt = function() {
    return (new Date())+"> ";
};

The .mongorc.js file is a good place to set your prompt if you want to always use a custom one (or set up a couple of custom prompts that you can switch between in the shell).


Inconvenient Collection Names

Fetching a collection with the db.collectionName syntax almost always works, unless the collection name is a reserved word or is an invalid JavaScript property name.

For example, suppose we are trying to access the version collection. We cannot say db.version because db.version is a method on db (it returns the version of the running MongoDB server):

> db.version
function () {
    return this.serverBuildInfo().version;
}

To actually access the version collection, you must use the getCollection function:

> db.getCollection("version")
test.version

This can also be used for collection names with characters that aren’t valid JavaScript property names, such as:

foo-bar-baz and 123abc (JavaScript property names can only contain letters, numbers, $ and _, and cannot start with a number).

Another way of getting around invalid properties is to use array-access syntax. In JavaScript, x.y is identical to x['y'].

This means that subcollections can be accessed using variables, not just literal names. Thus, if you needed to perform some operation on every blog subcollection, you could iterate through them with something like this:

test> var collections = ["posts", "comments", "authors"];

test> for (var i in collections) {
...     print(db.blog[collections[i]]);
... }

test.blog.posts
test.blog.comments
test.blog.authors

instead of this:

print(db.blog.posts);
print(db.blog.comments);
print(db.blog.authors);

Note that you cannot do db.blog.i, which would be interpreted as test.blog.i, not test.blog.posts. You must use the db.blog[i] syntax for i to be interpreted as a variable.

You can use this technique to access awkwardly named collections:

> var name = "@#&!"
> db[name].find()

Attempting to query db.@#&! would be illegal, but db[name] would work.

posted @ 2024-08-05 21:02  seveN1foR  阅读(13)  评论(0编辑  收藏  举报