Console log in MongoDB Shell - mongodb

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");

Related

MongoDB countDocuments() is returning an object, not a number

I'm starting to learn about mongoose/MongoDB aggregation functions, and am having some basic difficulties. For example, I'm trying to do the following:
var myModels= require('./models/myModel');
var myCount = myModels.countDocuments({userID: "A"});
console.log(myCount );
I just want to count the number of documents with userID of "A" but when this prints to the console, it's printing as a whole object, instead of just a numerical count. I've read the answer here but I'm still not able to solve this problem (also, is there a way, unlike in that question, to return the count directly rather than having to predefine a variable and set it in a callback function?)
I'm trying to follow the guide here and don't see where I'm going wrong.
It's because the return value of countDocuments is a promise and not a number.
You either need to wait for that Promise or use callback syntax like so:
var myModels= require('./models/myModel');
// this required the code to be inside an async function
var myCount = await myModels.countDocuments({userID: "A"});
console.log(myCount);
Or:
var myModels= require('./models/myModel');
myModels.countDocuments({userID: "A"})
.then((myCount) =>{console.log(myCount);});

NHibernate: Can't Select after Skip Take In Certain Scenario

For some reason I am unable to use Select() after a Skip()/Take() unless I do this in a certain way. The following code works and allows me to use result as part of a sub query.
var query = QueryOver.Of<MyType>();
query.Skip(1);
var result = query.Select(myType => myType.Id);
However, if I attempt to create the query on one line as below I can't compile.
var query = QueryOver.Of<MyType>().Skip(1);
var result = query.Select(myType => myType.Id);
It looks like the code in the first results in query being of type QueryOver< MyType, MyType> while the second results in query being of type QueryOver< MyType>.
It also works if written like this.
var query = QueryOver.Of<MyType>().Select(myType => myType.Id).Skip(1);
Any ideas why the second version fails horribly when the first and third versions work? It seems like odd behavior.
You have a typo in the second version...
var query = QueryOver.Of<MyType().Skip(1);
is missing the >
var query = QueryOver.Of<MyType>().Skip(1);
Not sure if thats what you where looking for.

What's wrong with my Meteor publication?

I have a publication, essentially what's below:
Meteor.publish('entity-filings', function publishFunction(cik, queryArray, limit) {
if (!cik || !filingsArray)
console.error('PUBLICATION PROBLEM');
var limit = 40;
var entityFilingsSelector = {};
if (filingsArray.indexOf('all-entity-filings') > -1)
entityFilingsSelector = {ct: 'filing',cik: cik};
else
entityFilingsSelector = {ct:'filing', cik: cik, formNumber: { $in: filingsArray} };
return SB.Content.find(entityFilingsSelector, {
limit: limit
});
});
I'm having trouble with the filingsArray part. filingsArray is an array of regexes for the Mongo $in query. I can hardcode filingsArray in the publication as [/8-K/], and that returns the correct results. But I can't get the query to work properly when I pass the array from the router. See the debugged contents of the array in the image below. The second and third images are the client/server debug contents indicating same content on both client and server, and also identical to when I hardcode the array in the query.
My question is: what am I missing? Why won't my query work, or what are some likely reasons it isn't working?
In that first screenshot, that's a string that looks like a regex literal, not an actual RegExp object. So {$in: ["/8-K/"]} will only match literally "/8-K/", which is not the same as {$in: [/8-K/]}.
Regexes are not EJSON-able objects, so you won't be able to send them over the wire as publish function arguments or method arguments or method return values. I'd recommend sending a string, then inside the publish function, use new RegExp(...) to construct a regex object.
If you're comfortable adding new methods on the RegExp prototype, you could try making RegExp an EJSON-able type, by putting this in your server and client code:
RegExp.prototype.toJSONValue = function () {
return this.source;
};
RegExp.prototype.typeName = function () {
return "regex";
}
EJSON.addType("regex", function (str) {
return new RegExp(str);
});
After doing this, you should be able to use regexes as publish function arguments, method arguments and method return values. See this meteorpad.
/8-K/.. that's a weird regex. Try /8\-K/.
A minus (-) sign is a range indicator and usually used inside square brackets. The reason why it's weird because how could you even calculate a range between 8 and K? If you do not escape that, it probably wouldn't be used to match anything (thus your query would not work). Sometimes, it does work though. Better safe than never.
/8\-K/ matches the string "8-K" anywhere once.. which I assume you are trying to do.
Also it would help if you would ensure your publication would always return something.. here's a good area where you could fail:
if (!cik || !filingsArray)
console.error('PUBLICATION PROBLEM');
If those parameters aren't filled, console.log is probably not the best way to handle it. A better way:
if (!cik || !filingsArray) {
throw "entity-filings: Publication problem.";
return false;
} else {
// .. the rest of your publication
}
This makes sure that the client does not wait unnecessarily long for publications statuses as you have successfully ensured that in any (input) case you returned either false or a Cursor and nothing in between (like surprise undefineds, unfilled Cursors, other garbage data.

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.