Как выполнить команды 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
может работать не на всех платформах.