Bagaimana cara menjalankan perintah mongo melalui skrip shell?


404

Saya ingin menjalankan mongoperintah dalam skrip shell, misalnya dalam skrip test.sh:

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

Ketika saya menjalankan skrip ini melalui ./test.sh, maka koneksi ke MongoDB dibuat, tetapi perintah berikut ini tidak dijalankan.

Bagaimana cara menjalankan perintah lain melalui skrip shell test.sh?

Jawaban:


452

Anda juga dapat mengevaluasi perintah menggunakan --evalbendera, jika hanya satu perintah.

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

Harap perhatikan: jika Anda menggunakan operator Mongo, dimulai dengan tanda $, Anda harus melingkupi argumen eval dalam tanda kutip tunggal untuk menjaga shell dari mengevaluasi operator sebagai variabel lingkungan:

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

Kalau tidak, Anda mungkin melihat sesuatu seperti ini:

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

35
Untuk .find()operasi, Anda perlu memanggil operasi pada objek hasil untuk mencetak dokumen, seperti toArray()atau shellPrint(). misalnya,mongo userdb --eval "printjson(db.users.find().toArray())"
Gingi

4
Saya harus menentukan string koneksi seperti mongo <ip>: <port> / db --eval "printjson (db.serverStatus ())" atau mongo <ip>: <port> / db <mongoCommands.js untuk mencegahnya selalu terhubung ke "test"
dev

9
Terima kasih @Gingi - metode pilihan saya adalah mongo mydb --eval "db.users.find({a:'b'}).pretty().shellPrint()"... simples :)
Matt Fletcher

4
Saya berharap saya akan mendapatkan SEMUA dari hasil, alih-alih melihatnya keluar "ketik 'itu' untuk lebih"
Randy L

6
@Amida dapat Anda lakukan mongo --eval "db.version()" --quietmisalnya untuk menghindari pencetakan semua suara yang Anda katakan
Fermin Silva

327

Masukkan skrip mongo Anda ke dalam .jsfile.

Kemudian jalankan mongo < yourFile.js

Ex:

demo.js // file memiliki skrip Anda

use sample  //db name
show collections

simpan file ini di "c: \ db-scripts"

Kemudian dalam cmd prompt buka "c: \ db-scripts"

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

Ini akan mengeksekusi kode dalam mongo dan menunjukkan output

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>

13
Secara harfiah .. Anda mengambil perintah yang sama persis dengan yang Anda masukkan ke mongo shell, menyimpan perintah-perintah itu ke .jsfile, dan meneruskannya sebagai parameter ke mongoperintah.
Matt

7
Perlu dicatat apa pun yang Anda tetapkan dalam pernyataan --eval (jika disediakan) ke mongo interpreter akan tetap berada dalam ruang lingkup ketika skrip Anda (jika disediakan) dieksekusi. Anda dapat menggunakan ini membuat skrip Anda lebih dapat digunakan kembali, misalnya. mongo --eval "somevar = 'someval';" db_name script_that_uses_somevar.js
Andrew J

9
@Matt - Perhatikan bahwa perintah non-JavaScript yang disediakan shell tidak tersedia dalam file JavaScript yang dieksekusi, jadi use dbNamedan show dbsakan bekerja dari prompt internal shell tetapi tidak dari dalam .jsfile. Ada persamaan JavaScript untuk perintah non-JavaScript, jadi ini bukan batasan, hanya sesuatu yang perlu Anda ketahui.
Tad Marshall

4
Jika Anda perlu menentukan nama basis data, nama pengguna, kata sandi, Anda dapat melakukannyamongo dbName -u userName -p "password with spaces" scriptToRun.js
KevinL

1
apakah ada cara untuk menjaga mongo prompt tetap terbuka? AKA Saya tidak ingin mongo mengatakan "selamat tinggal" kepada saya.
Alexander Mills


64

Masukkan ini ke dalam file bernama test.js:

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

kemudian jalankan dengan mongo myDbName test.js.


2
Bagaimana cara mengirimkan nilai ke skrip dari bash? Saya ingin memasukkan nama ke db yang tersedia dalam bash sebagai variabel dan saya ingin meneruskannya ke skrip (js)
Sasikanth

Ini adalah solusi yang jauh lebih baik, Ketika saya mem-pipe file ke mongo saya mendapatkan kesalahan sintaks js.
Storm Muller

41

Ada halaman dokumentasi resmi tentang ini juga.

Contoh dari halaman itu termasuk:

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

32

Script shell di bawah ini juga bekerja dengan baik untuk saya ... pasti harus menggunakan redirect yang disebutkan Antonin pada awalnya ... yang memberi saya ide untuk menguji dokumen di sini.

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

13
Jawaban bagus! Untuk banyak perintah, ini juga berfungsi:echo -e "use mydb\ndb.leads.findOne()\ndb.leads.find().count()" | mongo
Dennis Münkle

Sangat berguna karena Anda tidak dapat menggunakan "use mydb" dalam file JS.
buzypi

Terima kasih untuk ini! Akhirnya saya bisa menelepon use another_db. :-)
Ionică Bizău

1
Sebenarnya Anda dapat mengganti DB dari dalam skrip mongo:db = db.getSiblingDB('otherdb');
joeytwiddle

Apa yang saya butuhkan. Namun jika Anda hanya perlu menggunakan satu basis data, Anda dapat meneruskan nama basis data ke perintah mongo, mis mongo mydb <<EOF. Dll
spikyjt

22

Dalam pengaturan saya, saya harus menggunakan:

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

20

Saya menggunakan sintaks "heredoc", yang David Young sebutkan. Tapi ada yang menangkap:

#!/usr/bin/sh

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

Di atas TIDAK akan berfungsi, karena frasa "$ ada" akan terlihat oleh shell dan diganti dengan nilai variabel lingkungan bernama "ada." Yang, sepertinya, tidak ada, jadi setelah ekspansi shell, itu menjadi:

#!/usr/bin/sh

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

Agar dapat melewati Anda memiliki dua opsi. Satu jelek, satu cukup bagus. Pertama, yang jelek: lepas tanda $:

#!/usr/bin/sh

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

Saya TIDAK merekomendasikan ini, karena mudah lupa untuk melarikan diri.

Opsi lainnya adalah keluar dari EOF, seperti ini:

#!/usr/bin/sh

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

Sekarang, Anda dapat meletakkan semua tanda dolar yang Anda inginkan di heredoc Anda, dan tanda dolar diabaikan. Sisi bawah: Itu tidak berfungsi jika Anda perlu meletakkan parameter / variabel shell di skrip mongo Anda.

Opsi lain yang bisa Anda mainkan adalah mengacaukan shebang Anda. Sebagai contoh,

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

Ada beberapa masalah dengan solusi ini:

  1. Ini hanya berfungsi jika Anda mencoba membuat skrip shell mongo dapat dieksekusi dari baris perintah. Anda tidak dapat mencampur perintah shell biasa dengan perintah shell mongo. Dan semua yang Anda hemat dengan melakukannya adalah tidak harus mengetikkan "mongo" pada baris perintah ... (cukup alasan, tentu saja)

  2. Fungsinya persis seperti "mongo <some-js-file>" yang artinya tidak membiarkan Anda menggunakan perintah "use <db>".

Saya telah mencoba menambahkan nama database ke shebang, yang menurut Anda akan berhasil. Sayangnya, cara sistem memproses garis shebang, semuanya setelah spasi pertama dilewatkan sebagai parameter tunggal (seperti dikutip) ke perintah env, dan env gagal menemukan dan menjalankannya.

Sebagai gantinya, Anda harus menyematkan perubahan database di dalam skrip itu sendiri, seperti:

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

Seperti halnya apa pun dalam hidup, "ada lebih dari satu cara untuk melakukannya!"


18

Jika Anda mengaktifkan otentikasi:

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

16

Buat file skrip; tulis perintah:

#!/bin/sh
mongo < file.js

Dalam file.jstuliskan mongo query Anda:

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


12

Seperti yang disarankan oleh theTuxRacer, Anda dapat menggunakan perintah eval , bagi mereka yang melewatkannya seperti saya, Anda juga dapat menambahkan nama db Anda jika Anda tidak mencoba untuk melakukan operasi sebelumnya pada db default.

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

7

Terima kasih printf ! Di lingkungan Linux, berikut ini cara yang lebih baik untuk hanya menjalankan satu file saja. Katakanlah Anda memiliki dua file, mongoCmds.jsdengan banyak perintah:

use someDb
db.someColl.find()

dan kemudian file shell driver, runMongoCmds.sh

mongo < mongoCmds.js

Sebagai gantinya, miliki hanya satu file, mengandung runMongoCmds.sh

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

Bash printfjauh lebih kuat daripada echodan memungkinkan \nperintah antara memaksa mereka di beberapa baris.



6

Dalam kasus saya, saya dapat dengan mudah digunakan \nsebagai pemisah untuk perintah mongo berikutnya yang ingin saya jalankan kemudian pipa merekamongo

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

4

--shell flag juga dapat digunakan untuk file javascript

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

Saya pikir ini hanya membiarkan shell terbuka setelah dieksekusi? mongo /path/to/jsfile/test.jsakan exectute js juga.
UpTheCreek

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

3

Baru-baru ini bermigrasi dari mongodb ke Postgres. Ini adalah bagaimana saya menggunakan skrip.

mongo < scripts.js > inserts.sql

Baca scripts.jsdan hasilkan redirect ke inserts.sql.

scripts.js terlihat seperti ini

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 terlihat seperti ini

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

1
Sangat menarik, tapi di luar topik yang berkaitan dengan pertanyaan awal.
jlyonsmith

How to execute mongo commands through shell scripts?Ini bukan di luar topik. Sebenarnya, saya mencapai pertanyaan ini karena judulnya. Jadi orang-orang seperti saya mendapat manfaat membaca jawaban seperti itu. Juga, saya memberikan metode yang sangat berguna dalam contoh daripada contoh mainan.
mitos pembuat

2

Jika Anda ingin mengatasinya dengan satu baris, itu cara yang mudah.

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

cat file.sh | mongo <EXPECTED_COLLECTION>

1

Saya menulis berbagai opsi untuk Menjalankan Skrip Shell Mongo dari dalam skrip Bash yang lebih besar


1

Solusi skrip shell tunggal dengan kemampuan menyampaikan argumen mongo ( --quiet, dbname, dll):

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

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

The -Sbendera mungkin tidak bekerja pada semua platform.


0

Ketika menggunakan replaset, penulisan harus dilakukan pada PRIMARY, jadi saya biasanya menggunakan sintaksis seperti ini yang menghindari harus mencari tahu host mana yang merupakan master:

mongo -host myReplicaset/anyKnownReplica

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.