Linux脚本执行MongoDB查询,关于mongodb:如何通过shell脚本执行mongo命令?
我想在shell脚本中执行mongo命令,例如 在脚本test.sh中:#!/bin/shmongo myDbNamedb.mycollection.findOne()show collections当我通过./test.sh执行此脚本时,将建立与MongoDB的连接,但不执行以下命令。如何通过shell脚本test.sh执行其他命令?您还可以使用--eval标志评估命令,如果它只是一个命令。mo
我想在shell脚本中执行mongo命令,例如 在脚本test.sh中:
#!/bin/sh
mongo myDbName
db.mycollection.findOne()
show collections
当我通过./test.sh执行此脚本时,将建立与MongoDB的连接,但不执行以下命令。
如何通过shell脚本test.sh执行其他命令?
您还可以使用--eval标志评估命令,如果它只是一个命令。
mongo --eval"printjson(db.serverStatus())"
请注意:如果您使用的是Mongo运算符,从$符号开始,您需要用单引号括起eval参数,以防止shell将运算符作为环境变量进行求值:
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 :
对于.find()操作,您需要对结果对象调用操作以打印文档,例如toArray()或shellPrint()。例如,mongo userdb --eval"printjson(db.users.find().toArray())"
我必须指定连接字符串,如mongo :/ db --eval"printjson(db.serverStatus())"或mongo :/ db 谢谢@Gingi - 我的首选方法是mongo mydb --eval"db.users.find({a:'b'}).pretty().shellPrint()" ... simples :)
我希望我能得到所有的结果,而不是看到它为"更多"打字"打字"
虽然这有效,但问题是不仅发送了查询结果而且还发送了连接状态消息等噪声:MongoDB shell版本:2.6.0连接到:myhost DBQuery:mydb.mycollection - > {} MongoDB shell版本:2.6 .0连接到:myhost query result更多噪音
如何定义我的servername和dbname?
@Amida你可以做mongo --eval"db.version()" --quiet,以避免打印你说的所有噪音
如果您想要有效的JSON输出,请使用JSON.stringify()而不是printjson()
mongo --eval"db.test.update({"name":"foo"},{$set:{"this":"that"}});"> E QUERY SyntaxError: Unexpected token :如果您看到此错误,请不要尝试使用单引号或双引号中的文本$ set来解决此问题,这会导致数据丢失,因为脚本会将$set理解为新属性且没有$ set,文档被新文档覆盖,其中包含一些像"": this:"that"这样的字段。
双引号版本如果你转义任何这样的$运算符都有效:mongo --eval"db.${Collection}.updateMany({},{ \$set: {${Field}:${Value}}});"允许包含内联的shell标记
@colintobing mongo dbname --eval 'db.test.findOne()'
将您的mongo脚本放入.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
这将在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>
从字面上看......您可以使用与输入到mongo shell完全相同的命令,将这些命令保存到.js文件中,并将其作为参数传递给mongo命令。
值得注意的是,在执行脚本(如果提供)时,mongo解释器的--eval语句(如果提供)中设置的任何内容都将保留在范围内。您可以使用它使您的脚本更具可重用性,例如。 mongo --eval"somevar ='someval';" db_name script_that_uses_somevar.js
@Matt - 请注意,shell提供的非JavaScript命令在执行的JavaScript文件中不可用,因此use dbName和show dbs将在shell的内部提示符下工作,但不能在.js文件中工作。非JavaScript命令有JavaScript等价物,因此这不是限制,只是您需要注意的事项。
如果需要指定数据库的名称,用户名,密码,则可以执行mongo dbName -u userName -p"password with spaces" scriptToRun.js
如果你想要一个动态行为,即传递参数:mongo < demo.js arg1 arg2 arg3 - 这将如何在js文件中读取它们?
有没有办法让mongo提示打开? AKA我不希望mongo对我说"再见"。
如何在远程服务器上运行此脚本?mongodb:uri:mongodb:// user:password@mongodb01d.mydomain.com:27017 / mydb
使用mongo --quiet表示不打印再见和版本。
这在Linux下适用于我:
mongo < script.js
当然,它不必是.js文件
即使在Windows上也能工作
在PowerShell中不起作用,在Bash中有效
把它放在一个名为test.js的文件中:
db.mycollection.findOne()
db.getCollectionNames().forEach(function(collection) {
print(collection);
});
然后用mongo myDbName test.js运行它。
如何从bash传递值到脚本?我想在db中插入名称作为变量,我希望将其传递给脚本(js)
这在PowerShell中有效
这是一个更好的解决方案,当我将文件传输到mongo时,我得到js语法错误。
还有一个关于此的官方文档页面。
该页面的示例包括:
mongo server:27017/dbname --quiet my_commands.js
mongo test --eval"printjson(db.getCollectionNames())"
下面的shell脚本对我来说也很好用...明确必须使用Antonin最初提到的重定向...这给了我测试这里文档的想法。
function testMongoScript {
mongo <
use mydb
db.leads.findOne()
db.leads.find().count()
EOF
}
很棒的答案!对于多个命令,这也有效:echo -e"use mydb
db.leads.findOne()
db.leads.find().count()" | mongo
绝对有用,因为你不能在JS文件中使用"use mydb"。
这次真是万分感谢!最后我可以打电话给use another_db。 :-)
实际上,您可以在mongo脚本中切换DB:db = db.getSiblingDB('otherdb');
在我的设置中,我必须使用:
mongo --host="the.server.ip:port" databaseName theScript.js
Thx为主机名标志
+1为databaseName :)
我使用了David Young提到的"heredoc"语法。但是有一个问题:
#!/usr/bin/sh
mongo ;lt;db;gt; ;lt;;lt;EOF
db.;lt;collection;gt;.find({
fieldName: { $exists: true }
})
.forEach( printjson );
EOF
以上操作不起作用,因为shell将看到短语"$ exists",并用名为"exists"的环境变量的值替换。哪个可能不存在,所以在shell扩展后,它变为:
#!/usr/bin/sh
mongo ;lt;db;gt; ;lt;;lt;EOF
db.;lt;collection;gt;.find({
fieldName: { : true }
})
.forEach( printjson );
EOF
为了让它通过你有两个选择。一个是丑陋的,一个是相当不错的。首先,丑陋的一个:逃避$符号:
#!/usr/bin/sh
mongo ;lt;db;gt; ;lt;;lt;EOF
db.;lt;collection;gt;.find({
fieldName: { \$exists: true }
})
.forEach( printjson );
EOF
我不推荐这个,因为很容易忘记逃避。
另一个选择是逃避EOF,如下所示:
#!/usr/bin/sh
mongo ;lt;db;gt; ;lt;;lt;\EOF
db.;lt;collection;gt;.find({
fieldName: { $exists: true }
})
.forEach( printjson );
EOF
现在,您可以将所需的所有美元符号放在您的heredoc中,并忽略美元符号。缺点:如果你需要在你的mongo脚本中放置shell参数/变量,这不起作用。
你可以玩的另一个选择是弄乱你的shebang。例如,
#!/bin/env mongo
;lt;some mongo stuff;gt;
此解决方案有几个问题:
它仅在您尝试从命令行生成mongo shell脚本时才有效。您不能将常规shell命令与mongo shell命令混合使用。而你所节省的就是不必在命令行输入"mongo"......(理由当然,这样)
它的功能与"mongo; lt; some-js-file; gt;"完全相同这意味着它不允许你使用"use; lt; db; gt;"命令。
我已经尝试将数据库名称添加到shebang,您认为它可以工作。不幸的是,系统处理shebang行的方式,第一个空格之后的所有内容都作为单个参数(如同引用)传递给env命令,并且env无法找到并运行它。
相反,您必须在脚本本身中嵌入数据库更改,如下所示:
#!/bin/env mongo
db = db.getSiblingDB(';lt;db;gt;');
;lt;your script;gt;
与生活中的任何事物一样,"有多种方法可以做到!"
这个对我有用:#!/ usr / bin / mongo; lt; db_name; gt;
如果您启用了身份验证:
mongo -u username -p password --authenticationDatabase auth_db_name ;lt; your_script.js
这个怎么样:
echo"db.mycollection.findOne()" | mongo myDbName
echo"show collections" | mongo myDbName
或者更具可读性:echo; quot; db.mycollection.findOne(); quot;| mongo myDbName --quiet | python -m json.tool
这对于在加载.mongorc之后执行某些操作很有用(docs.mongodb.org/manual/reference/program/mongo/;hellip;)
正如theTuxRacer所建议的那样,您可以使用eval命令,对于那些像我一样丢失它的人,如果您不想在默认数据库上执行操作,也可以添加数据库名称。
mongo ;lt;dbname;gt; --eval"printjson(db.something.find())"
谢谢你包括命令的;lt;dbname;gt;部分:)
创建一个脚本文件; 写命令:
#!/bin/sh
mongo ;lt; file.js
在file.js中编写您的mongo查询:
db.collection.find({"myValue":null}).count();
谢谢printf!在Linux环境中,这是一个更好的方法,只有一个文件运行show。假设您有两个文件,mongoCmds.js包含多个命令:
use someDb
db.someColl.find()
然后是驱动程序shell文件,runMongoCmds.sh
mongo ;lt; mongoCmds.js
相反,只有一个文件,runMongoCmds.sh包含
printf"use someDb
db.someColl.find()" | mongo
Bash的printf比echo更强大,并允许命令之间的强制它们在多行上。
mongo db_name --eval"db.user_info.find().forEach(function(o) {print(o._id);})"
mongo ;lt;;lt;EOF
use ;lt;db_name;gt;
db.getCollection(";lt;collection_name;gt;").find({})
EOF
或者对于短命令:mongo ;lt;;lt;;lt; ;#39;show dbs;#39;
--shell标志也可用于javascript文件
mongo --shell /path/to/jsfile/test.js
我认为这只是在js执行后打开shell? mongo ;#47;path;#47;to;#47;jsfile;#47;test.js也会对js进行解释。
如果你想用一条线处理它,这是一个简单的方法。
file.sh --;gt; db.EXPECTED_COLLECTION.remove("_id":1234)
cat file.sh | mongo ;lt;EXPECTED_COLLECTION;gt;
在我的情况下,我可以方便地使用作为我要执行的下一个mongo命令的分隔符,然后将它们传递给mongo
echo $'use your_db
db.yourCollection.find()' | mongo
最近从mongodb迁移到Postgres。 这就是我使用脚本的方式。
mongo ;lt; scripts.js ;gt; 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');
非常有趣,但关于原始问题的主题。
How to execute mongo commands through shell scripts?这不是偏离主题的。 事实上,由于标题,我达成了这个问题。 所以像我这样的人有益于阅读这样的答案。 另外,我在示例中给出了一个非常有用的方法,而不是玩具示例。
我在更大的Bash脚本中编写了运行Mongo Shell脚本的各种选项
单shell脚本解决方案,能够传递mongo参数(--quiet,dbname等):
#!/usr/bin/env -S mongo --quiet localhost:27017/test
cur = db.myCollection.find({});
while(cur.hasNext()) {
printjson(cur.next());
}
-S标志可能不适用于所有平台。
更多推荐
所有评论(0)