Kabuk komut dosyaları aracılığıyla mongo komutları nasıl çalıştırılır?


403

mongoKabuk komut dosyasında, örneğin bir komut dosyasında komutları yürütmek istiyorum test.sh:

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

Bu komut dosyasını çalıştırdığımda ./test.sh, MongoDB bağlantısı kurulur, ancak aşağıdaki komutlar yürütülmez.

Kabuk betiği üzerinden diğer komutlar nasıl çalıştırılır test.sh?

Yanıtlar:


452

Bir komutu --eval, yalnızca tek bir komutsa, bayrağını kullanarak da değerlendirebilirsiniz .

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

Lütfen dikkat: Mongo operatörlerini kullanıyorsanız, $ işaretiyle başlayarak kabuğun operatörü ortam değişkeni olarak değerlendirmesini engellemek için değerlendirme bağımsız değişkenini tek tırnak içine almak istersiniz:

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

Aksi takdirde şöyle bir şey görebilirsiniz:

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

35
İçin .find()operasyonlar, aşağıdakiler gibi belgeleri yazdırmak için sonuç nesne üzerinde bir işlem çağırmanız gerekir toArray()ya shellPrint(). ör.,mongo userdb --eval "printjson(db.users.find().toArray())"
Gingi

4
Bunu önlemek için mongo <ip>: <port> / db --eval "printjson (db.serverStatus ())" veya mongo <ip>: <port> / db <mongoCommands.js gibi bağlantı dizesini belirtmek zorunda kaldım her zaman "test" bağlanma
dev

9
Thanks @Gingi - tercih ettiğim yöntem mongo mydb --eval "db.users.find({a:'b'}).pretty().shellPrint()"... simples :)
Matt Fletcher

4
keşke daha fazla bilgi için "yazın 'bu' primt görmek yerine, sonuçların TÜM olsun istiyorum
Randy L

6
@Amida mongo --eval "db.version()" --quiet, örneğin söylediğiniz tüm gürültüyü yazdırmaktan kaçınabilirsiniz
Fermin Silva

327

Mongo betiğinizi bir .jsdosyaya yerleştirin.

Sonra yürütün mongo < yourFile.js

Ör:

demo.js // dosyanızın betiği var

use sample  //db name
show collections

bu dosyayı "c: \ db-scripts" de tut

Sonra cmd isteminde "c: \ db-scripts" e gidin

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

Bu kod mongo'da yürütülür ve çıktıyı gösterir

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
Kelimenin tam anlamıyla .. mongo kabuğuna gireceğiniz komutların aynısını alıyorsunuz, bu komutları bir .jsdosyaya kaydediyor ve mongokomuta parametre olarak iletiyorsunuz.
Matt

7
Mongo yorumlayıcısına bir --eval ifadesinde (sağlanmışsa) ayarladığınız herhangi bir şeyin, komut dosyanız (sağlanmışsa) yürütüldüğünde kapsamda kalacağını belirtmek gerekir. Bunu, komut dosyalarınızı daha yeniden kullanılabilir hale getirmek için kullanabilirsiniz, örn. mongo --eval "somevar = 'someval';" db_name script_that_uses_somevar.js
Andrew J

9
@Matt - JavaScript olmayan kabuk bir infaz JavaScript dosyası bulunmayan sağladığını komutları, böylece Not use dbNameve show dbskabuk iç istemi ancak bir içeriden gelen çalışacak .jsdosyası. JavaScript olmayan komutlar için JavaScript eşdeğerleri vardır, bu nedenle bu bir sınırlama değildir, yalnızca bilmeniz gereken bir şeydir.
Tad Marshall

4
Bir veritabanı adı, kullanıcı adı, şifre belirtmeniz gerekiyorsa, şunları yapabilirsinizmongo dbName -u userName -p "password with spaces" scriptToRun.js
KevinL

1
mongo istemini açık tutmanın bir yolu var mı? AKA Mongo'nun bana "güle güle" demesini istemiyorum.
Alexander Mills


64

Bunu şu adlı bir dosyaya koyun test.js:

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

sonra ile çalıştırın mongo myDbName test.js.


2
Bash'dan betiğe değerler nasıl aktarılır? Ben bash değişken olarak kullanılabilir db içine isim eklemek istiyorum ve ben komut dosyası (js) geçmek istiyorum
Sasikanth

Bu çok daha iyi bir çözüm, Ben mongo bir dosyada boru Ben js sözdizimi hataları alıyorum.
Storm Muller

41

Bununla ilgili resmi bir belge sayfası da var.

Bu sayfadaki örnekler şunları içerir:

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

32

Aşağıdaki kabuk betiği de benim için iyi çalıştı ... kesin, Antonin'in ilk başta bahsettiği yönlendirmeyi kullanmak zorundaydı ... bu bana bu belgeyi test etme fikri verdi.

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

13
Mükemmel cevap! Birden fazla komut için bu da işe echo -e "use mydb\ndb.leads.findOne()\ndb.leads.find().count()" | mongo
yarar

JS dosyasında "use mydb" kullanamadığınız için kesinlikle kullanışlıdır.
buzypi

Bunun için teşekkür ederim! Sonunda arayabilirim use another_db. :-)
Ionică Bizău

1
Aslında DB bir mongo komut dosyası içinden değiştirebilirsiniz:db = db.getSiblingDB('otherdb');
joeytwiddle

Tam ihtiyacım olan şey. Ancak, yalnızca bir veritabanı kullanmanız gerekiyorsa, veritabanı adını örneğin mongo komutuna mongo mydb <<EOF
geçirebilirsiniz

22

Kurulumumda şunları kullanmalıyım:

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

20

David Young'ın bahsettiği "heredoc" sözdizimini kullanıyorum. Ancak bir sorun var:

#!/usr/bin/sh

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

Yukarıdakiler işe yaramaz, çünkü "$ exist" ifadesi kabuk tarafından görülecek ve "exist" adlı ortam değişkeninin değeri ile değiştirilecektir. Muhtemelen mevcut değil, bu yüzden kabuk genişlemesinden sonra:

#!/usr/bin/sh

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

Geçebilmesi için iki seçeneğiniz var. Biri çirkin, biri gayet güzel. İlk olarak, çirkin olan: $ işaretlerinden kaç:

#!/usr/bin/sh

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

Ben bunu tavsiye ETMEM, çünkü kaçmayı unutmak kolaydır.

Diğer seçenek EOF'tan kaçmaktır, şöyle:

#!/usr/bin/sh

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

Şimdi, heredocunuza istediğiniz tüm dolar işaretlerini koyabilirsiniz ve dolar işaretleri göz ardı edilir. Aşağı tarafı: Mongo betiğinize kabuk parametreleri / değişkenleri koymanız gerekiyorsa bu işe yaramaz.

Birlikte oynayabileceğiniz bir diğer seçenek, mesleğinizle uğraşmaktır. Örneğin,

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

Bu çözümle ilgili birkaç sorun var:

  1. Yalnızca bir mongo kabuk betiğini komut satırından yürütülebilir hale getirmeye çalışıyorsanız çalışır. Normal kabuk komutlarını mongo kabuk komutlarıyla karıştıramazsınız. Ve bunu yaparak kaydettiğiniz tek şey komut satırına "mongo" yazmak zorunda kalmamaktır ... (yeterli sebep, elbette)

  2. Tam olarak "mongo <some-js-file>" gibi işlev görür, yani "use <db>" komutunu kullanmanıza izin vermez.

İşe yarayacağını düşündüğünüz shebang'a veritabanı adı eklemeyi denedim. Ne yazık ki, sistemin shebang hattını işleme şekli, ilk boşluktan sonraki her şey env komutuna (alıntılanmış gibi) tek bir parametre olarak geçirilir ve env onu bulamaz ve çalıştırmaz.

Bunun yerine, veritabanı değişikliğini komut dosyasının içine yerleştirmelisiniz, şöyle:

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

Hayattaki her şeyde olduğu gibi, "bunu yapmanın birden fazla yolu var!"


18

Kimlik doğrulamanın etkin olması durumunda:

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

16

Bir komut dosyası oluşturun; yazma komutları:

#!/bin/sh
mongo < file.js

In file.jsyazma senin Mongo sorgusu:

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


12

Tarafından önerildiği gibi eval komutunu theTuxRacerkullanabilirsiniz, benim gibi eksik olanlar için, varsayılan db üzerinde işlemi önceden yapmaya çalışmıyorsanız, db adınızı ekleyebilirsiniz.

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

7

Teşekkürler printf! Bir Linux ortamında, şovu çalıştırmak için sadece bir dosyanın daha iyi bir yolu var. mongoCmds.jsBirden fazla komut içeren iki dosyanız olduğunu varsayalım:

use someDb
db.someColl.find()

ve sonra sürücü kabuk dosyası, runMongoCmds.sh

mongo < mongoCmds.js

Bunun yerine, sadece bir dosya var, runMongoCmds.sh içeren

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

Bash's printfdaha güçlü echove izin verir\n komutları komutlar arasında birden çok satıra zorlanmasına .



6

Benim durumumda, \nyürütmek istediğim bir sonraki mongo komutu için ayırıcı olarak rahatça kullanabilirim .mongo

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

4

- kabuk bayrağı javascript dosyaları için de kullanılabilir

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

Sanırım bu js yürütüldükten sonra kabuğu açık bırakır? mongo /path/to/jsfile/test.jsjs de uygulayacaktır.
UpTheCreek

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

3

Son zamanlarda mongodb'dan Postgres'e göç etti. Senaryoları böyle kullandım.

mongo < scripts.js > inserts.sql

scripts.jsVe çıktı yönlendirmesini okuyun inserts.sql.

scripts.js buna benzer

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 buna benzer

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

1
Orijinal soru ile ilgili olarak çok ilginç, ama konu dışı.
jlyonsmith

How to execute mongo commands through shell scripts?Bu konu dışı değil. Aslında bu soruya başlık yüzünden ulaştım. Benim gibi insanlar böyle bir cevabı okumaktan faydalanırlar. Ayrıca, örnekte bir oyuncak örneği yerine çok kullanışlı bir yöntem veriyorum.
mythicalcoder

2

Eğer tek bir çizgiyle işlemek istiyorsanız bu kolay bir yoldur.

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

cat file.sh | mongo <EXPECTED_COLLECTION>

1

Daha büyük bir Bash betiğinden bir Mongo Kabuk Betiği Çalıştırmak için çeşitli seçenekler yazdım


1

Mongo argümanlarını ( --quiet, dbname, vb.) Geçirme yeteneğine sahip tek kabuklu komut dosyası çözümü :

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

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

-SBayrak tüm platformlarda çalışmayabilir.


0

Bir replikaset kullanırken, yazmalar PRIMARY üzerinde yapılmalıdır, bu yüzden genellikle hangi ana bilgisayarın ana olduğunu bulmak zorunda kalmaz böyle sözdizimi kullanın:

mongo -host myReplicaset/anyKnownReplica

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.