it-swarm.com.de

Wie führe ich Mongo-Befehle über Shell-Skripte aus?

Ich möchte mongo Befehle in einem Shell-Skript ausführen, z. in einem Skript test.sh:

#!/bin/sh
mongo myDbName
db.mycollection.findOne()
show collections

Wenn ich dieses Skript über ./test.sh ausführe, wird die Verbindung zu MongoDB hergestellt, die folgenden Befehle werden jedoch nicht ausgeführt.

Wie führe ich andere Befehle über das Shell-Skript test.sh aus?

352
StackOverFlow

Sie können einen Befehl auch mit dem Flag --eval auswerten, wenn es sich nur um einen einzelnen Befehl handelt.

mongo --eval "printjson(db.serverStatus())"

Bitte beachten Sie: Wenn Sie Mongo-Operatoren verwenden und mit einem $ -Zeichen beginnen, müssen Sie das eval-Argument in einfache Anführungszeichen setzen, damit die Shell den Operator nicht als Umgebungsvariable auswertet:

mongo --eval 'db.mycollection.update({"name":"foo"},{$set:{"this":"that"}});' myDbName

Andernfalls sehen Sie möglicherweise Folgendes:

mongo --eval "db.test.update({\"name\":\"foo\"},{$set:{\"this\":\"that\"}});"
> E QUERY    SyntaxError: Unexpected token :
399
theTuxRacer

Fügen Sie Ihr Mongo-Skript in eine .js -Datei ein.

Dann führe mongo < yourFile.js aus

Ex:

die Datei demo.js // enthält Ihr Skript

use sample  //db name
show collections

behalte diese Datei in "c:\db-scripts"

Dann gehen Sie in cmd Prompt zu "c:\db-scripts"

C:\db-scripts>mongo < demo.js

Dadurch wird der Code in Mongo ausgeführt und die Ausgabe angezeigt

C:\db-scripts>mongo < demo.js
Mongo Shell version: 3.0.4
Connecting to: test
switched to db sample
users   //collection name
tasks   //collection name
bye
C:\db-scripts>
295
Matt

Das funktioniert bei mir unter Linux:

mongo < script.js
92

Fügen Sie dies in eine Datei mit dem Namen test.js ein:

db.mycollection.findOne()
db.getCollectionNames().forEach(function(collection) {
  print(collection);
});

führen Sie es dann mit mongo myDbName test.js aus.

59
Theo

Es gibt auch eine offizielle Dokumentation Seite darüber.

Beispiele von dieser Seite sind:

mongo server:27017/dbname --quiet my_commands.js
mongo test --eval "printjson(db.getCollectionNames())"
39
thaddeusmt

Das folgende Shell-Skript funktionierte auch gut für mich ... musste definitiv die Umleitung verwenden, die Antonin zuerst erwähnte ... und brachte mich auf die Idee, das Dokument hier zu testen.

function testMongoScript {
    mongo <<EOF
    use mydb
    db.leads.findOne()
    db.leads.find().count()
EOF
}
28
David H. Young

In meinem Setup muss ich verwenden:

mongo --Host="the.server.ip:port" databaseName theScript.js 
21
Ed Williams

Ich benutze die "heredoc" -Syntax, die David Young erwähnt. Aber es gibt einen Haken:

#!/usr/bin/sh

mongo <db> <<EOF
db.<collection>.find({
  fieldName: { $exists: true }
})
.forEach( printjson );
EOF

Das Obige funktioniert NICHT, da der Ausdruck "$ exists" von der Shell gesehen und durch den Wert der Umgebungsvariablen "exists" ersetzt wird. Was wahrscheinlich nicht existiert, wird nach der Shell-Erweiterung zu:

#!/usr/bin/sh

mongo <db> <<EOF
db.<collection>.find({
  fieldName: { : true }
})
.forEach( printjson );
EOF

Um es passieren zu lassen, haben Sie zwei Möglichkeiten. Einer ist hässlich, einer ist ganz nett. Erstens, der Hässliche: Entkomme den $ -Zeichen:

#!/usr/bin/sh

mongo <db> <<EOF
db.<collection>.find({
  fieldName: { \$exists: true }
})
.forEach( printjson );
EOF

Ich empfehle dies NICHT, da es leicht ist, die Flucht zu vergessen.

Die andere Möglichkeit besteht darin, dem EOF zu entkommen:

#!/usr/bin/sh

mongo <db> <<\EOF
db.<collection>.find({
  fieldName: { $exists: true }
})
.forEach( printjson );
EOF

Jetzt können Sie alle gewünschten Dollarzeichen in Ihren Heredoc einfügen, und die Dollarzeichen werden ignoriert. Der Nachteil: Das funktioniert nicht, wenn Sie Shell-Parameter/-Variablen in Ihr Mongo-Skript einfügen müssen.

Eine andere Möglichkeit, mit der Sie spielen können, ist, sich mit Ihrem Shebang herumzuschlagen. Zum Beispiel,

#!/bin/env mongo
<some mongo stuff>

Es gibt mehrere Probleme mit dieser Lösung:

  1. Dies funktioniert nur, wenn Sie versuchen, ein Mongo-Shell-Skript über die Befehlszeile ausführbar zu machen. Sie können keine regulären Shell-Befehle mit Mongo-Shell-Befehlen mischen. Und alles, was Sie dadurch sparen, ist, dass Sie nicht "mongo" in die Befehlszeile eingeben müssen ... (Grund genug natürlich)

  2. Es funktioniert genau wie "mongo <some-js-file>", was bedeutet, dass Sie den Befehl "use <db>" nicht verwenden können.

Ich habe versucht, dem Shebang den Datenbanknamen hinzuzufügen, von dem Sie denken, dass es funktionieren würde. Leider wird bei der Art und Weise, wie das System die Shebang-Zeile verarbeitet, alles nach dem ersten Leerzeichen als einzelner Parameter (wie in Anführungszeichen gesetzt) ​​an den Befehl env übergeben, und env kann ihn nicht finden und ausführen.

Stattdessen müssen Sie die Datenbankänderung wie folgt in das Skript selbst einbetten:

#!/bin/env mongo
db = db.getSiblingDB('<db>');
<your script>

Wie bei allem im Leben, "gibt es mehr als einen Weg, es zu tun!"

18
John Arrowwood

Falls Sie die Authentifizierung aktiviert haben:

mongo -u username -p password --authenticationDatabase auth_db_name < your_script.js
14
Moses Xu

Wie wäre es damit:

echo "db.mycollection.findOne()" | mongo myDbName
echo "show collections" | mongo myDbName
13
Mark Butler

Wie von theTuxRacer vorgeschlagen, können Sie den Befehl eval verwenden. Für diejenigen, die es wie ich vermissen, können Sie auch Ihren Datenbanknamen hinzufügen, wenn Sie nicht versuchen, eine Operation durchzuführen die voreingestellte db.

mongo <dbname> --eval "printjson(db.something.find())"
12
Matt Clark

Erstellen Sie eine Skriptdatei. Befehle schreiben:

#!/bin/sh
mongo < file.js

In file.js schreiben Sie Ihre Mongo-Abfrage:

db.collection.find({"myValue":null}).count();
11
GSK

Danke printf! In einer Linux-Umgebung ist es besser, wenn nur eine Datei die Show ausführt. Angenommen, Sie haben zwei Dateien, mongoCmds.js mit mehreren Befehlen:

use someDb
db.someColl.find()

und dann die Treiber-Shell-Datei runMongoCmds.sh

mongo < mongoCmds.js

Verwenden Sie stattdessen nur eine Datei, die runMongoCmds.sh enthält

printf "use someDb\ndb.someColl.find()" | mongo

Bashs printf ist viel robuster als echo und ermöglicht es, dass \n zwischen Befehlen sie auf mehrere Zeilen zwingt.

7
tgoneil

--Shell Flag kann auch für Javascript-Dateien verwendet werden

 mongo --Shell /path/to/jsfile/test.js 
4
Jackson Harry
mongo db_name --eval "db.user_info.find().forEach(function(o) {print(o._id);})"
4
Talespin_Kit
mongo <<EOF
use <db_name>
db.getCollection("<collection_name>").find({})
EOF
4
Erdem ÖZDEMİR

In meinem Fall kann ich \n bequem als Trennzeichen für den nächsten Mongo-Befehl verwenden, den ich ausführen möchte, und sie dann an mongo weiterleiten.

echo $'use your_db\ndb.yourCollection.find()' | mongo
2
Ardhi

Wenn Sie mit einer Zeile arbeiten möchten, ist dies ein einfacher Weg.

file.sh --> db.EXPECTED_COLLECTION.remove("_id":1234)

cat file.sh | mongo <EXPECTED_COLLECTION>
2
Erçin Akçay

I geschrieben die verschiedenen Optionen zum Ausführen eines Mongo-Shell-Skripts in einem größeren Bash-Skript

1
PKD

Kürzlich von Mongodb nach Postgres gewandert. So habe ich die Skripte benutzt.

mongo < scripts.js > inserts.sql

Lesen Sie den scripts.js und leiten Sie die Ausgabe an inserts.sql weiter.

scripts.js sieht so aus

use myDb;
var string = "INSERT INTO table(a, b) VALUES";
db.getCollection('collectionName').find({}).forEach(function (object) {
    string += "('" + String(object.description) + "','" + object.name + "'),";
});
print(string.substring(0, string.length - 1), ";");

inserts.sql sieht so aus

INSERT INTO table(a, b) VALUES('abc', 'Alice'), ('def', 'Bob'), ('ghi', 'Claire');
1
mythicalcoder

Single Shell-Skriptlösung mit der Möglichkeit, Mongo-Argumente (--quiet, Datenbankname usw.) zu übergeben:

#!/usr/bin/env -S mongo --quiet localhost:27017/test

cur = db.myCollection.find({});
while(cur.hasNext()) {
  printjson(cur.next());
}

Das -S -Flag funktioniert möglicherweise nicht auf allen Plattformen.

0
yǝsʞǝla