Comment exécuter des commandes mongo via des scripts shell?

Je veux exécuter des commandes mongo dans un script shell.

J'ai essayé de manière suivante test.sh

#!/bin/sh

mongo myDbName

db.mycollection.findOne()

show collections

Quand j'exécute le script ci-dessus. /test.sh

Puis connexion mongo établie mais les commandes suivantes ne sont pas exécutées

Comment exécuter d'autres commandes via le script sh [test.sh] ?

S'il vous Plaît aidez-moi

294
demandé sur Tim Cooper 2011-01-29 18:26:01

19 réponses

Vous pouvez également évaluer une commande en utilisant 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 un 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.test.update({"name":"foo"},{$set:{"this":"that"}});'

Sinon vous pouvez voir quelque chose comme ceci:

mongo --eval "db.test.update({\"name\":\"foo\"},{$set:{\"this\":\"that\"}});"
> E QUERY    SyntaxError: Unexpected token :
340
répondu theTuxRacer 2015-07-16 19:59:54

Mettez votre script mongo dans un fichier .js.

Puis exécutez mongo < yourFile.js

Ex:

Démo.le fichier js / / 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

Cela exécutera le code dans 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>
260
répondu Matt 2015-10-28 06:45:44

Cela fonctionne pour moi sous Linux:

mongo < script.js
90
répondu Antonin Brettsnajdr 2011-07-31 18:05:04

Mettre ça dans un fichier appelé test.js:

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

Puis exécutez-le avec mongo myDbName test.js.

50
répondu Theo 2011-01-29 18:36:47

Il y a aussi une pagedocumentation officielle à ce sujet.

Voici quelques exemples de cette page:

mongo server:27017/dbname --quiet my_commands.js
mongo test --eval "printjson(db.getCollectionNames())"
33
répondu thaddeusmt 2013-04-27 20:00:45

Le script shell ci-dessous a également bien fonctionné pour moi... definite a dû utiliser la redirection qu'Antonin a mentionnée au début... cela m'a donné l'idée de tester le document ici.

function testMongoScript {
    mongo <<EOF
    use mydb
    db.leads.findOne()
    db.leads.find().count()
EOF
}
24
répondu David H. Young 2011-08-21 04:44:34

Dans ma configuration, je dois utiliser:

mongo --host="the.server.ip:port" databaseName theScript.js 
18
répondu Ed Williams 2012-02-03 19:42:35

Que diriez-vous de ceci:

echo "db.mycollection.findOne()" | mongo myDbName
echo "show collections" | mongo myDbName
12
répondu Mark Butler 2014-09-08 17:40:29

Comme suggéré par theTuxRacer, vous pouvez utiliser la commande eval, pour ceux qui la manquent comme je l'étais, vous pouvez également ajouter votre nom de base de données si vous n'essayez pas de préforme opération sur la base de données par défaut.

mongo <dbname> --eval "printjson(db.something.find())"
12
répondu Matt Clark 2015-12-22 20:07:43

J'utilise la syntaxe" heredoc", que David Young mentionne. Mais il y a 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 l'expression "$exists " sera vue par le shell et remplacée par la valeur de la variable d'environnement nommée "exists."Ce qui, probablement, n'existe pas, donc après l'expansion du 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. L'un est moche, l'autre est plutôt gentil. Tout d'abord, le moche: échapper aux signes$:

#!/usr/bin/sh

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

Je ne le recommande pas, 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 dollar que vous voulez dans votre heredoc, et le dollar signes sont ignorés. L'inconvénient: cela ne fonctionne pas si vous avez besoin de mettre des paramètres/variables shell dans votre script mongo.

Une autre option avec 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 cela solution:

  1. Cela ne fonctionne que si vous essayez de faire un script shell mongo exécutable à partir de la ligne de commande. Vous ne pouvez pas mélanger les commandes shell régulières avec les commandes shell mongo. Et tout ce que vous enregistrez en le faisant n'est pas d'avoir à taper "mongo" sur la ligne de commande... (une raison suffisante, bien sûr)

  2. Il fonctionne exactement comme "mongo " ce qui signifie qu'il ne vous permet pas d'utiliser la commande "use ".

J'ai essayé d'ajouter le nom de la base de données pour le shebang, que vous pensez fonctionnerait. Malheureusement, la façon dont le système traite la ligne shebang, tout après le premier espace est passé en tant que paramètre unique (comme s'il était entre guillemets) à la commande env, et env ne parvient pas à le trouver et à l'exécuter.

Au lieu de cela, vous devez intégrer le changement de base de données dans le script lui-même, comme ceci:

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

Comme avec n'importe quoi dans la vie, "il y a plus d'une façon de le faire!"

11
répondu John Arrowwood 2014-08-29 14:19:08

Si l'authentification est activée:

mongo -u username -p password --authenticationDatabase auth_db_name < your_script.js
8
répondu Moses Xu 2017-06-02 00:11:06

Merci printf! Dans un environnement Linux, voici une meilleure façon d'avoir un seul fichier 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, avoir un seul fichier, runMongoCmds.sh contenant

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

printf de Bash est beaucoup plus robuste que echo et permet aux \n entre les commandes de les forcer sur plusieurs lignes.

7
répondu tgoneil 2015-12-17 21:27:57

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();
7
répondu GSK 2017-08-21 16:37:30
mongo db_name --eval "db.user_info.find().forEach(function(o) {print(o._id);})"
4
répondu Talespin_Kit 2016-12-06 15:30:29

--coque drapeau peut également être utilisé pour les fichiers javascript

 mongo --shell /path/to/jsfile/test.js 
3
répondu Jackson Harry 2015-04-30 12:57:41

Si vous voulez le gérer avec une ligne, c'est un moyen facile.

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

cat file.sh | mongo <EXPECTED_COLLECTION>
2
répondu Erçin Akçay 2018-01-22 15:50:07
mongo <<EOF
use <db_name>
db.getCollection("<collection_name>").find({})
EOF
1
répondu Erdem ÖZDEMİR 2018-04-27 07:38:00

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
0
répondu Ardhi 2018-08-29 09:57:43

Récemment migré de mongodb vers Postgres. C'est ainsi que j'ai utilisé les scripts.

mongo < scripts.js > inserts.sql

Lisez le scripts.js et la redirection de sortie vers inserts.sql.

scripts.js on dirait 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 on dirait ceci

INSERT INTO table(a, b) VALUES('abc', 'Alice'), ('def', 'Bob'), ('ghi', 'Claire');
-1
répondu mythicalcoder 2017-05-07 07:30:24