MongoDB: Custom command defined in .mongorc.js - mongodb

I'd like to define a custom Mongo shell command. Given .mongorc.js is like below:
var dbuc;
(function () {
dbuc = (function () {
return db.getName().toUpperCase();
})();
})();
I'm getting proper upper-cased name for initial database, yet when I switch to other database I'm still getting name of the initial database instead of current one.
> db
test
> dbuc
TEST
> use otherbase
> db
otherbase
> dbuc
TEST
I see .mongorc.js is run before mongo runs and that's why dbuc variable has assigned value of initial database - test. But I rather wonder how to get a name of current database whatever base I turned on.

There are a few things to note:
In mongo shell, typeof db is a javascript object and typeof dbuc is string.
I believe, in your code, dbuc value is assigned once and does not change when use is called.
use is a shellHelper function(type shellHelper.use in mongo shell). It reassigns variable db with newly returned database object.
One of the solutions, for dbuc to work, is to add following code to .mongorc.js
// The first time mongo shell loads, assign the value of dbuc.
dbuc = db.getName().toUpperCase();
shellHelper.use = function (dbname) {
var s = "" + dbname;
if (s == "") {
print("bad use parameter");
return;
}
db = db.getMongo().getDB(dbname);
// After new assignment, extract and assign upper case
// of newly assgined db name to dbuc.
dbuc = db.getName().toUpperCase();
print("switched to db " + db.getName());
};

Related

Can't get CoffeeScript to recognize a function in a js file

I am writing a simple app in Coffeescript to control a Philips Hue light. I have included this module into my project. The below code seems to work fine up until I try to set the color of the lights using setLightState. The compiler says the function isn't a function. I don't quite understand why it doesn't recognize the function.
# Connect with Philips Hue bridge
jsHue = require 'jshue'
hue = jsHue()
# Get the IP address of any bridges on the network
hueBridgeIPAddress = hue.discover().then((bridges) =>
if bridges.length is 0
console.log 'No bridges found. :('
else
(b.internalipaddress for b in bridges)
).catch((e) => console.log 'Error finding bridges', e)
if hueBridgeIPAddress.length isnt 0 # if there is at least 1 bridge
bridge = hue.bridge(hueBridgeIPAddress[0]) #get the first bridge in the list
# Create a user on that bridge (may need to press the reset button on the bridge before starting the tech buck)
user = bridge.createUser('myApp#testdevice').then((data) =>
username = data[0].success.username
console.log 'New username:', username
bridge.user(username)
)
if user?
#assuming a user was sucessfully created set the lighting to white
user.setLightState(1, {on:true, sat:0, bri:100, hue:65280}).then((data) =>
# process response data, do other things
)
As you can see on the github page of the jshue lib, bridge.createUser does not directly return a user object.
Instead the example code sets the user variable inside the then function of the returned promise:
bridge.createUser('myApp#testdevice').then(data => {
// extract bridge-generated username from returned data
var username = data[0].success.username;
// instantiate user object with username
var user = bridge.user(username);
user.setLightState( .... )
});
It can be expected that - using this approach - the user variable will be set correctly and user.setLightState will be defined.
A self-contained example:
Take this Codepen for example:
url = "https://api.ipify.org?format=json"
outside = axios.get(url).then (response) =>
inside = response.data.ip
console.log "inside: #{inside}"
inside
console.log "outside: #{outside}"
The console output is
outside: [object Promise]
inside: 178.19.212.102
You can see that:
the outside log is first and is a Promise object
the inside log comes last and contains the actual object from the Ajax call (in this case your IP)
the then function implicitly returning inside does not change anything

Console log in MongoDB Shell

I want to write functions into MongoDB Shell like this:
var last = function(collection) { db[collection].find().sort({_id: -1}).limit(1).toArray(); }
But there is one problem. When I call last() function, it will make no output. How to fix it?
You need to use either use the JavaScript print() function or the mongo specific printjson() function which returns formatted JSON to actually log to output the result from the find method, for example:
var last = function(collection) {
var doc = db.getCollection(collection).find().sort({_id: -1}).limit(1).toArray();
printjson(doc);
};
last("test");

Flask-MongoKit find_one()

I'm trying to use Flask-MongoKit as follows (with both attempts to find_one failing):
app = Flask('app-name')
db = MongoKit(app)
db.register([database.Users])
with app.app_context():
print db['users'].find_one()
print db.Users.find_one()
When I used plain MongoKit (non-Flask version), and this worked (as follows)
db = Connection()
db.register([database.Users])
print db.Users.find_one()
Thanks!
EDIT:
The database and collection are defined as follows.
class Users(Document):
__collection__ = 'users'
__database__ = 'database'
Flask-MongoKit doesn't use MongoKit's __database__ value. Instead, it uses an application config setting named MONGODB_DATABASE. If that isn't set, it defaults to a database named flask. If you change your code to
app = Flask('app-name')
app.config['MONGODB_DATABASE'] = 'database'
db = MongoKit(app)
your calls to find_one() should work.
The relative bits can be found here and here.

MongoDB eval() with arguments

I'm getting a strange result when trying to use eval with the args argument. The following works fine:
> db.eval(function(coll) {
var res = db[coll].find({});
return(res.count());
}, ['KenColl'])
1438
But when I pass a second argument, I always get empty results, even if I don't use it:
> db.eval(function(coll, query) {
var res = db[coll].find({});
return(res.count());
}, ['KenColl', {}])
0
Am I misunderstanding something about eval and args? I'm running version 2.4.3 of both mongod and the MongoDB shell.
For db.eval you shouldn't pass the arguments as an array, just pass them into the function.
The following example should work:
db.eval(function(coll, query) {
var res = db[coll].find(query);
return(res.count());
}, 'KenColl', {})
p.s. your first example only works because in javascript db['KenColl'] === db[['KenColl']]

Avoid printing output in mongo client

I am working with mongo client. Sometimes the output of some commands I execute involve an enormous output, which mongo prints on screen. How can I avoid this?
There is a way to suppress output.
Using "var x = ...;" allows to hide output of expressions.
But there are other commands that harder to suppress like
Array.prototype.distinct = function() {
return [];
}
This produces printing of new defined function.
To suppress it you will need to write it in this way:
var suppressOutput = (
Array.prototype.distinct = function() {
return [];
}
);
Per the comment by #WiredPrairie, this solution worked for me:
Just set the return value to a local variable: var x=db.so.find(); and inspect it as needed.