Как выполнять команды монго через скрипты оболочки? - PullRequest
347 голосов
/ 29 января 2011

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

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

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

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

Ответы [ 20 ]

390 голосов
/ 14 мая 2011

Вы также можете оценить команду, используя флаг --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 :
291 голосов
/ 29 января 2011

Поместите ваш скрипт монго в файл .js.

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

Пример:

demo.js // файл содержит ваш скрипт

use sample  //db name
show collections

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

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

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

Это будетвыполнить код в монго и показывает вывод

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>
93 голосов
/ 31 июля 2011

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

mongo < script.js
58 голосов
/ 29 января 2011

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

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

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

38 голосов
/ 18 апреля 2012

Существует также официальная документация на эту страницу.

Примеры с этой страницы включают:

mongo server:27017/dbname --quiet my_commands.js
mongo test --eval "printjson(db.getCollectionNames())"
28 голосов
/ 21 августа 2011

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

function testMongoScript {
    mongo <<EOF
    use mydb
    db.leads.findOne()
    db.leads.find().count()
EOF
}
21 голосов
/ 03 февраля 2012

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

mongo --host="the.server.ip:port" databaseName theScript.js 
18 голосов
/ 29 августа 2014

Я использую синтаксис "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.

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

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

Существует несколько проблем с этим решением:

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

  2. Он работает точно так же, как "mongo""Это означает, что это не позволяет использовать команду" use ".

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

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

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

Как и во всем в жизни, «существует более одного способа сделать это!»

14 голосов
/ 02 июня 2017

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

mongo -u username -p password --authenticationDatabase auth_db_name < your_script.js
13 голосов
/ 08 сентября 2014

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

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