Je souhaite exécuter les commandes mongo
dans un script Shell, par exemple. dans un script test.sh
:
#!/bin/sh
mongo myDbName
db.mycollection.findOne()
show collections
Lorsque j'exécute ce script via ./test.sh
, la connexion à MongoDB est établie mais les commandes suivantes ne sont pas exécutées.
Comment exécuter d'autres commandes via le script shell test.sh
?
Vous pouvez également évaluer une commande à l'aide de l'indicateur --eval
, s'il ne s'agit que d'une seule commande.
mongo --eval "printjson(db.serverStatus())"
Remarque: Si vous utilisez des opérateurs Mongo, en commençant par le signe $, vous voudrez entourer l'argument eval de guillemets simples pour empêcher le shell d'évaluer l'opérateur en tant que variable d'environnement:
mongo --eval 'db.mycollection.update({"name":"foo"},{$set:{"this":"that"}});' myDbName
Sinon, vous pouvez voir quelque chose comme ceci:
mongo --eval "db.test.update({\"name\":\"foo\"},{$set:{\"this\":\"that\"}});"
> E QUERY SyntaxError: Unexpected token :
Mettez votre script mongo dans un fichier .js
.
Puis exécutez mongo < yourFile.js
Ex:
demo.js // le fichier a votre script
use sample //db name
show collections
conservez ce fichier dans "c:\db-scripts"
Ensuite, dans l'invite cmd, allez à "c:\db-scripts"
C:\db-scripts>mongo < demo.js
Ceci exécutera le code en Mongo et affichera la sortie
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>
Cela fonctionne pour moi sous Linux:
mongo < script.js
Mettez ceci dans un fichier nommé test.js
:
db.mycollection.findOne()
db.getCollectionNames().forEach(function(collection) {
print(collection);
});
puis exécutez-le avec mongo myDbName test.js
.
Il existe également une page documentation officielle à ce sujet.
Les exemples de cette page incluent:
mongo server:27017/dbname --quiet my_commands.js
mongo test --eval "printjson(db.getCollectionNames())"
Le script Shell ci-dessous a également bien fonctionné pour moi. Il était clair que je devais utiliser la redirection mentionnée au début par Antonin ... qui me donna l’idée de tester le document ici.
function testMongoScript {
mongo <<EOF
use mydb
db.leads.findOne()
db.leads.find().count()
EOF
}
Dans ma configuration, je dois utiliser:
mongo --Host="the.server.ip:port" databaseName theScript.js
J'utilise la syntaxe "heredoc", que David Young mentionne. Mais il ya un hic:
#!/usr/bin/sh
mongo <db> <<EOF
db.<collection>.find({
fieldName: { $exists: true }
})
.forEach( printjson );
EOF
Ce qui précède NE fonctionnera PAS, car la phrase "$ existe" sera vue par le shell et remplacée par la valeur de la variable d'environnement nommée "existe". Ce qui, probablement, n'existe pas, donc après l'expansion de Shell, il devient:
#!/usr/bin/sh
mongo <db> <<EOF
db.<collection>.find({
fieldName: { : true }
})
.forEach( printjson );
EOF
Pour le faire passer, vous avez deux options. On est moche, on est assez gentil. Tout d'abord, le vilain: échapper aux signes $:
#!/usr/bin/sh
mongo <db> <<EOF
db.<collection>.find({
fieldName: { \$exists: true }
})
.forEach( printjson );
EOF
Je ne recommande pas cela, car il est facile d'oublier de s'échapper.
L'autre option est d'échapper à l'EOF, comme ceci:
#!/usr/bin/sh
mongo <db> <<\EOF
db.<collection>.find({
fieldName: { $exists: true }
})
.forEach( printjson );
EOF
Maintenant, vous pouvez mettre tous les signes du dollar que vous voulez dans votre heredoc, et les signes du dollar sont ignorés. L'inconvénient: cela ne fonctionne pas si vous devez insérer des paramètres/variables du shell dans votre script Mongo.
Une autre option à laquelle vous pouvez jouer est de jouer avec votre Shebang. Par exemple,
#!/bin/env mongo
<some mongo stuff>
Il y a plusieurs problèmes avec cette solution:
Cela ne fonctionne que si vous essayez de créer un script shell mongo à partir de la ligne de commande. Vous ne pouvez pas mélanger des commandes Shell régulières avec des commandes Shell mongo. Et tout ce que vous enregistrez en faisant cela n’a pas à taper "mongo" sur la ligne de commande ... (raison suffisante, bien sûr)
Il fonctionne exactement comme "mongo <some-js-file>", ce qui signifie qu'il ne vous permet pas d'utiliser la commande "use <db>".
J'ai essayé d'ajouter le nom de la base de données au Shebang, ce qui pourrait marcher. Malheureusement, de la même manière que le système traite la ligne Shebang, tout ce qui suit le premier espace est transmis à la commande env en tant que paramètre unique (comme s'il était entre guillemets), et env ne parvient pas à le trouver ni à l'exécuter.
Au lieu de cela, vous devez incorporer le changement de base de données dans le script lui-même, comme suit:
#!/bin/env mongo
db = db.getSiblingDB('<db>');
<your script>
Comme dans toute vie, "il y a plus d'une façon de le faire!"
Si vous avez activé l'authentification:
mongo -u username -p password --authenticationDatabase auth_db_name < your_script.js
Que dis-tu de ça:
echo "db.mycollection.findOne()" | mongo myDbName
echo "show collections" | mongo myDbName
Comme suggéré par theTuxRacer
, vous pouvez utiliser la commande eval; pour ceux qui le manquent comme je le faisais, vous pouvez également ajouter votre nom de base de données si vous n'essayez pas de préformer l'opération sur la base de données par défaut.
mongo <dbname> --eval "printjson(db.something.find())"
Créer un fichier de script; écrire des commandes:
#!/bin/sh
mongo < file.js
Dans file.js
écrivez votre requête Mongo:
db.collection.find({"myValue":null}).count();
Merci printf
! Dans un environnement Linux, voici un meilleur moyen de n’avoir qu’un seul fichier pour exécuter le spectacle. Disons que vous avez deux fichiers, mongoCmds.js
avec plusieurs commandes:
use someDb
db.someColl.find()
puis le fichier shell du pilote, runMongoCmds.sh
mongo < mongoCmds.js
Au lieu de cela, ayez juste un fichier, runMongoCmds.sh contenant
printf "use someDb\ndb.someColl.find()" | mongo
Le printf
de Bash est beaucoup plus robuste que echo
et permet au \n
entre des commandes de les forcer sur plusieurs lignes.
--Le drapeau peut également être utilisé pour les fichiers javascript
mongo --Shell /path/to/jsfile/test.js
mongo db_name --eval "db.user_info.find().forEach(function(o) {print(o._id);})"
mongo <<EOF
use <db_name>
db.getCollection("<collection_name>").find({})
EOF
Dans mon cas, je peux facilement utiliser \n
comme séparateur pour la prochaine commande mongo que je veux exécuter, puis les diriger vers mongo
echo $'use your_db\ndb.yourCollection.find()' | mongo
Si vous voulez gérer cela avec une seule ligne, c'est un moyen simple.
file.sh --> db.EXPECTED_COLLECTION.remove("_id":1234)
cat file.sh | mongo <EXPECTED_COLLECTION>
I écrit les différentes options pour exécuter un script shell Mongo à partir d'un script Bash plus grand
Récemment migré de mongodb vers Postgres. Voici comment j'ai utilisé les scripts.
mongo < scripts.js > inserts.sql
Lisez le scripts.js
et la redirection de sortie vers inserts.sql
.
scripts.js
ressemble à ceci
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
ressemble à ceci
INSERT INTO table(a, b) VALUES('abc', 'Alice'), ('def', 'Bob'), ('ghi', 'Claire');
Solution de script à un seul shell avec possibilité de passer des arguments mongo (--quiet
, nombase, etc.):
#!/usr/bin/env -S mongo --quiet localhost:27017/test
cur = db.myCollection.find({});
while(cur.hasNext()) {
printjson(cur.next());
}
L’indicateur -S
risque de ne pas fonctionner sur toutes les plateformes.