Как выполнить команды mongo через shell-скрипты?

Я хочу выполнить команды mongo в сценарии оболочки, например, в сценарии test.sh:

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

Когда я выполняю этот скрипт через ./test.sh, то соединение с MongoDB устанавливается, но следующие команды не выполняются.

Как выполнить другие команды через скрипт сценария test.sh?

Ответ 1

Вы также можете оценить команду, используя флаг --eval, если это всего лишь одна команда.

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

Обратите внимание: если вы используете операторы Mongo, начиная со знака $, вам нужно заключить аргумент eval в одинарные кавычки, чтобы оболочка не оценивала оператор как переменную среды:

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

В противном случае вы можете увидеть что-то вроде этого:

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

Ответ 2

Поместите свой mongo script в файл .js.

Затем выполните mongo < yourFile.js

Пример:

demo.js//файл имеет ваш script

use sample  //db name
show collections

сохраните этот файл в "c:\db-scripts"

Затем в приглашении cmd перейдите к "c:\db-scripts"

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

Это приведет к выполнению кода в mongo и отобразит вывод

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>

Ответ 3

Это работает для меня под Linux:

mongo < script.js

Ответ 4

Поместите это в файл с именем test.js:

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

затем запустите его с помощью mongo myDbName test.js.

Ответ 5

Здесь есть страница официальная документация об этом.

Примеры из этой страницы:

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

Ответ 6

Оболочка script ниже также хорошо работала для меня... определенно пришлось использовать перенаправление, о котором упоминал Антонин вначале... это дало мне идею протестировать здесь документ.

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

Ответ 7

В моей настройке я должен использовать:

mongo --host="the.server.ip:port" databaseName theScript.js 

Ответ 8

Я использую синтаксис "heredoc", о котором упоминает Дэвид Янг. Но есть улов:

#!/usr/bin/sh

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

Вышеуказанное НЕ будет работать, потому что фраза "$ существует" будет видна оболочкой и заменена значением переменной среды с именем "существует". Который, вероятно, не существует, поэтому после расширения оболочки он становится:

#!/usr/bin/sh

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

Чтобы пройти, у вас есть два варианта. Один уродлив, один довольно приятный. Во-первых, уродливый: избегайте знака $:

#!/usr/bin/sh

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

Я НЕ рекомендую это, потому что легко забыть бежать.

Другой вариант - выйти из EOF, например:

#!/usr/bin/sh

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

Теперь вы можете поместить все ваши долларовые знаки в свой heredoc, а знаки доллара игнорируются. Нижняя сторона: это не работает, если вам нужно поместить параметры/переменные оболочки в свой mongo script.

Еще один вариант, с которым вы можете играть, - это возиться со своим shebang. Например,

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

Есть несколько проблем с этим решением:

  • Он работает только в том случае, если вы пытаетесь сделать из командной строки оболочку mongo script. Вы не можете смешивать обычные команды оболочки с командами оболочки mongo. И все, что вы сохраняете, не нужно набирать "манго" в командной строке... (конечно, разумно).

  • Он функционирует точно так же, как "mongo < some-js-file > "; что означает, что он не позволяет вам использовать "use <db> "; команда.

Я попытался добавить имя базы данных в shebang, что, по вашему мнению, будет работать. К сожалению, система обрабатывает строку shebang, все после первого пробела передается в качестве единственного параметра (как если бы он цитируется) команде env, а env не находит и не запускает его.

Вместо этого вам необходимо встроить изменение базы данных внутри самого script, например:

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

Как и в любом случае в жизни, "есть более чем один способ сделать это!"

Ответ 9

Если включена аутентификация:

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

Ответ 10

Как насчет этого:

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

Ответ 11

Как было предложено theTuxRacer, вы можете использовать команду eval, для тех, кто ее пропускает, как я был, вы также можете добавить свое имя db, если вы не пытаетесь выполнить операцию предварительной обработки по умолчанию db.

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

Ответ 12

Создайте файл script; написать команды:

#!/bin/sh
mongo < file.js

В file.js напишите свой запрос mongo:

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

Ответ 13

Спасибо printf! В среде Linux здесь лучше всего будет показывать только один файл. Скажем, у вас есть два файла, mongoCmds.js с несколькими командами:

use someDb
db.someColl.find()

а затем файл оболочки драйвера, runMongoCmds.sh

mongo < mongoCmds.js

Вместо этого, у вас есть только один файл, runMongoCmds.sh содержащий

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

Bash printf гораздо более надежный, чем echo, и позволяет \n между командами принудительно их на несколько строк.

Ответ 14

- флаг флага также может использоваться для файлов javascript

 mongo --shell /path/to/jsfile/test.js 

Ответ 15

mongo db_name --eval "db.user_info.find().forEach(function(o) {print(o._id);})"

Ответ 16

mongo <<EOF
use <db_name>
db.getCollection("<collection_name>").find({})
EOF

Ответ 17

В моем случае я могу удобно использовать \n качестве разделителя для следующей команды mongo, которую я хочу выполнить, затем mongo их в mongo

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

Ответ 18

Если вы хотите обработать его одной строкой, это простой способ.

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

cat file.sh | mongo <EXPECTED_COLLECTION>

Ответ 19

Недавно перенесено из mongodb в Postgres. Вот как я использовал скрипты.

mongo < scripts.js > inserts.sql

Считать scripts.js и перенаправить вывод на inserts.sql.

scripts.js выглядит следующим образом

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 выглядит следующим образом

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

Ответ 20

Я написал различные варианты запуска сценария оболочки Mongo из более крупного сценария Bash.

Ответ 21

Решение для единого сценария оболочки с возможностью передачи аргументов Монго (--quiet, имя базы данных и т.д.):

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

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

Флаг -S может работать не на всех платформах.