Mongo command line eval exits without error - bash

I can't seem to .remove() from the command line. My query works fine if I go into the mongo shell, but not directly from bash.
$ mongo mydatabase --eval 'db.mytable.remove({expires: {$lt: Math.round(new Date().getTime() / 1000)}})'
MongoDB shell version: 2.0.6
connecting to: mydatabase
This command takes hours to run on all of our data when run manually through the mongo shell. It returns instantly without error from the bash shell like above.
I know there's data and can confirm it with a similar --eval:
$ mongo mydatabase --eval 'printjson(db.mytable.findOne({expires: {$lt: Math.round(new Date().getTime() / 1000)}}))'
MongoDB shell version: 2.0.6
connecting to: mydatabase
{
"_id" : "39e493ccef9d58bf75d856f55fb269f6",
"value" : "mydata",
"expires" : NumberLong(1371486135)
}
Any ideas why the db.mytable.remove() fails without error?

I've tried now with MongoDB shell version: 2.2.2 and it works fine:
mongo test --eval 'db.things.remove({expires: {$lt: Math.round(new Date().getTime() / 1000)}})'
Try to update MongoDB to a newer version if you are not already updated, plus I heard that latests mongoDB version use V8 Javascript engine could be useful

It's possible that in the shell, remove is not using getLastError, and is therefore asynchronous. If you fire off the command, you can check db.currentOp() to see if there are any commands running.
It's also possible that your query as given is being interpreted in the shell in such a way that it's not matching any records to delete. Make sure that a find returns data using that same query.
It's also possible that 2.0.6's shell uses the second justOne parameter by default, making it find and delete the first matching record, at which point it'll return. You might try passing an explicit second parameter false to force it to multi-record mode. I don't have a 2.0.6 shell to test with, but it's something to check for.

Related

difference between execute shell script directly and through pipe

my shell script called mongoLogin.sh as below:
#!/bin/sh
mongo
use demo
show tables
the function of above is logining mongo and show tables of database called demo.
if I execute it directly by:
sh mongoLogin.sh
it works. however if I execute it by this way as below:
cat mongoLogin.sh | sh
compared with execute directly, it will exit automatically, as well as I ctrl+c after execute it directly. It seemed the sh command after pipe will create a new subprocess, and this subprocess finish due to some reason.
Do there exist some method that I can achieve same result by execute script through pipe?
update:
when execute directly it seemed only the first command make effect, because following commands are mongo operations rather than shell commands. And when I execute it by pipe, all commands make effect, but it exit automatically.
the output of executing it through pipe as below:
xxx#xxxMacBook-Pro:~/Downloads$cat mongoLogin.sh | sh
MongoDB shell version v4.0.3
connecting to: mongodb://127.0.0.1:27017
Implicit session: session { "id" : UUID("43c55950-f9e2-49ca-a458-
611f8c71eae4") }
MongoDB server version: 4.0.3
switched to db demo
test
bye
Both variants don't work, because use demo is not a valid shell command.
I have not worked with mongo, but if the command accepts is input from stdin, you can try
mongo <<OGNOM
use demo
show tables
OGNOM
Make sure that the final OGNOM starts in the first column of your line!

Impala shell - Hive Beeline - "Argument list too long"

I have a Cloudera cluster on which multiple impala jobs are running all the time (i.e. cronjobs containing impala-shell commands). However I have a few INSERT INTO queries that are unusually long: they contain a lot of 'CASE...WHEN...THEN' lines. When these queries are run in impala-shell the command fails with an error "Argument list too long". They run just fine in Hue, but can't get them to run on the commandline.
Are there any workarounds for this?
I've tried running the command via Hive beeline (instead of impala) and setting 'hive.script.operator.truncate.env = true'. Beeline failed with the same error. I've tried if calling the query from a separate file made any difference (it doesn't). Can I save the 'CASE...WHEN...THEN' lines in separate vars perhaps (using 'set') and call those in the query? Or would that be another dead-end? A colleague mentioned a User Defined Function (UDF) might help, but I'm not sure. Opinions?

How can I retrieve the result if I got a match of not in my MongoDB using a bash script

I look up a certain query in my MongoDB and echo the result. The output looks always the same:
MongoDB shell version: 2.4.9
connection to: foo_collection
bye
When I echo the result in a .txt file, I can see that an additional line is printed which gives me the desired result after the above mentioned string.
How can I get the result without the workaround by saving the echo of the result to a .txt file?
UPDATE
It seems, that mongodb produces a second time output after the connection information. I am only interested in the second output, how can I retrieve it?
From man mongo :
--quiet
Silences output from the shell during the connection process.
For instance, the following will only print the json result :
mongo --quiet --eval "printjson(db.getSiblingDB('myDB').getCollectionNames())"

mongo shell script won't let me include "use <database>"

32-bit mongo 2.0.1 on a windows XP machine
//script filename: test.js (one line shell script file to store a person)
db.cTest.save({Name: "Fred", Age:21});
run against database dbTest by entering the following 2 shell commands:
> use dbTest
switched to dbTest
> load("test.js")
So far, so good.
But if I try and include the "use" statement in the script it fails:
//script filename: test.js (including "use" statement)
use dbTest;
db.cTest.save({Name: "Fred", Age:21});
fails with error msg as follows:
> load("test.js")
SyntaxError: missing ; before statement
Mon Dec 19 11:56:31: Error: error loading js file temp.js (shell):1
Adding or removing semicolons to test.js doesn't seem to matter.
So how do you put a "use" directive into a mongo shell script?
In a mongo script you can use the db.getSiblingDB('new_db_name') to get a reference of a new database. So, it it not mandatory to give the database name in the command line. You can use the script.js:
db = db.getSiblingDB('new_db_name');
print(db);
// the rest of your code for database "new_db_name"
and the output of this script is (invoked with mongo script.js):
MongoDB shell version: 2.2.2
connecting to: test
sag
http://www.mongodb.org/display/DOCS/Scripting+the+shell
use dbname
This command does not work in scripted mode. Instead you will need to explicitly define the database in the connection (/dbname in the example above).
Alternately, you can also create a connection within the script:
db2 = connect("server:27017/otherdbname")
Well, it still is unfortunate that "load('file.js')" and "mongo file.js" don't actually use the same script interpreter as the interactive mongo shell. Opening the connection explicitly in the script is potentially a violation of the DRY principle because mongo already knows that information. What does work, though, is piping the file into mongo rather than passing its name on the command line:
mongo <file.js

Pass result of Curl request to mysql command line

SO this is a bit of an odd request but hoping someone on here knows some command line fu. Might have to post to serverfault too, we'll see.
I'm trying to figure out how i can pass the results of a curl request to the mysql command line application. So basically something kinda like this -
mysql --user=root --password=my_pass < (curl http://localhost:3000/application.sql)
where that URL returns basically a text response with sql statements.
Some context:
An application I am developing supports multiple installations, as part of the installation process for a new instance we spin up a copy of our "data" database for the new instance.
I'm trying to automate the deployment process as much as possible so I built a small "dashboard" app in rails that can generate the sql statements, config files, etc for each instance and also helps us see stats about the instances and other fun stuff. Now I'm writing capistrano tasks to actually do a deployment based on the ID of the installation which i pass in as a variable.
The initial deployment setup includes creating the applications database, which this sql request will do. I could in theory pull the file in a wget request, execute and delete it but I thought it would be cleaner to just tell the remote server to curl request it and execute it in one step.
So any ideas?
I'm fairly certain the syntax you have originally won't work as the '<' expects a file. Instead you want to pipe the output of curl, which by default prints to STDOUT to mysql.
I believe the following will work for you.
curl http://localhost:3000/application.sql | mysql --user=root --password=my_pass
In Bash, you can do process substitution:
mysql ... < <(curl ...)

Resources