MongoDB collection.aggregate usage to retrieve a count [duplicate] - mongodb

Why does my query not working with more than 100 documents in collection?
db.collection('allowedmacs').find().toArray(function(err, docs) {
console.log(docs);
}
err says this:
name: 'MongoError',
message: 'connection destroyed, not possible to instantiate cursor'
If documents <100 all works fine.

You're probably doing something like this:
db.collection('allowedmacs').find().toArray(function(err, docs) {
console.log(docs);
});
db.close();
So you're closing the database before the callback to toArray has been called (although it may work on some occassions).
Instead, try this:
db.collection('allowedmacs').find().toArray(function(err, docs) {
console.log(docs);
db.close();
});

in source there is written:
MongoDB supports no more than 100 levels of nesting for BSON documents.
maybe you look into : Mongo and find always limited to 100 with geo data

Related

MongoDB: Using lean on aggregate function

I'm trying to use the lean() option in order to speed up my queries. But when adding it to a query like this:
Pets.aggregate({ $match: { 'Name': 'Floofkins', 'lastMealDate': {$gt: today}}}, function (err, pets){
if (err) {
res.status(500).json({'error': err});
console.log('Could not fetch pets: ' + err);
return;
}
petsHadMealsToday = pets.length;
}).lean();
All I get is TypeError: Cannot read property 'lean' of undefined although pets.length returns the number of pets that matched the query.
If I'd remove the match option however and run something like below, it works like a charm.
Pets.aggregate({ 'Name': 'Floofkins', 'lastMealDate': {$gt: today}}, function (err, pets){
if (err) {
res.status(500).json({'error': err});
console.log('Could not fetch pets: ' + err);
return;
}
petsHadMealsToday = pets.length;
}).lean();
I guess I'm missing some fundamental point about how to use match and such, so feel free to educate me!
After reading a bit, this is my take on the answer to my question:
lean() is not needed on an aggregate function as the documents returned are plain JavaScript objects, and not Mongoose objects. This is because any shape of document can be returned. Source.
Therefore adding lean() to an aggregate function will generate an error since there is nothing to perform the lean() function upon.
No need to lean pipeline output . Aggregate output is already lean , using mongoose too
http://mongoosejs.com/docs/api.html#model_Model.aggregate
because output of aggregate pipeline is not a mongoose document

Getting an error using MongoDB aggregate $sample operation. -- MongoError: $sample stage could not find a non-duplicate document

MongoError: $sample stage could not find a non-duplicate document after 100 while using a random cursor. This is likely a sporadic failure, please try again.
Using MongoDB version 3.2.8 and just upgraded to 3.2.10.
I'm following the example set forth by the MongoDB documentation.. There is very little documentation. The only thing I can find doing a search is a bug in an issue queue which doesn't solve the problem for me.
My implementation is very simple.
function createBattle(done) {
// Need to make sure that the yachts are different.
async.doWhilst(
function(callback) {
Yacht.aggregate(
{
$sample: { size: 2 }
},
function (err, results) {
console.log(err.toString());
if (err) return callback(err);
callback(null, results);
}
)
},
function(results) {
return results.length !== 2 || _.isEqual(results[0]._id, results[1]._id);
},
function(err, results) {
if (err) return done(err);
done(null, results);
}
)
}
I'm not sure what is going on. Any ideas?
I am using Mongoose. It is in development. My guess is that something occurred when I changed the schema of the document. It works with the test mock data after creating 100000 fake documents or just 10 documents. So I decided to try a fresh start on the collection on the development instance of the database. Regardless, I exported the collection into a clean JSON file. I deleted the collection in the database. Then I imported the JSON dump. It works fine.
It's a bug.
This is probably the last straw with MongoDB for me. I'll probably go back to SQL, use Redis, and try PostGRES.

SAVE operation returning storage _id?

Is there a save operation in mongoose.js or mongodb api, which returns the _id of stored entry?
In mongoose the following will save the Entry.
p.save(function (err) {
if (err) return handleError(err);
else console.log('saved');
})
})
Likewise db.collection.save(document) will save document in mongodb api. But in both cases, you need to query db again for _id, which I want to avoid. As it seems ineffient.
When you instantiate an object in Mongoose, the object will have an _id already assigned (as it's assigned on the client by default).
So, if you just check:
console.log(p.id);
You'll see that it has a value before you call save.
And in the case of using the native driver for Node.JS, the document is returned in the result parameter with the _id set.
var collection = db.collection("tests");
collection.insert(p, function(err, results) {
if (err) { return; }
// results in an array, and in this case
// results[0]._id would be available
});

Getting Mongoose Schema's and Documents without knowing Schema / Collection names?

Short Version: I basically want to do what show collections does in the mongo shell, in mongoose.
Long Version:
I want to create an application that allows users to basically create their own Schema's > Collections > Documents using mongo + mongoose + node.js.
The first step of this application would be to show previously created Collections and their Documents. But since these would be created by a user their names are not known.
The code I've found that came closest was:
function find (collec, query, callback) {
mongoose.connection.db.collection(collec, function (err, collection) {
collection.find(query).toArray(callback);
});
}
But I don't know what the name of the collection is so I can't pass the 'collec' parameter.
So, anyone know how to get the list of collections without knowing their names?
I ended up using node-mongodb-native (the mongo driver that mongoose works on top of) to get the collection names:
var nmn_connect = require('mongoose/node_modules/mongodb').connect;
nmn_connect('mongo://localhost:27017/DATABASE', function(err, db) {
if(!err){
db.collectionNames(function(err, names){ // what I was looking for
if(!err){
console.log(names);
db.close();
}else{
console.log(err);
db.close();
}
});
}else{
console.log(err)
}
});
The Object returned by mongoose.connect() has no method similar to collectionNames() that I can find.
I know nothing of mongoose, but this page suggests that you could use mongoose.connection.collections to access all collections: http://mongoosejs.com/docs/api.html
each collection again should have a name attribute.
try this:
mongoose.connection.db.collectionNames(function (err, names) {
});

Identify last document from MongoDB find() result set

I'm trying to 'stream' data from a node.js/MongoDB instance to the client using websockets. It is all working well.
But how to I identify the last document in the result? I'm using node-mongodb-native to connect to MongoDB from node.js.
A simplified example:
collection.find({}, {}, function(err, cursor) {
if (err) sys.puts(err.message);
cursor.each(function(err, doc) {
client.send(doc);
});
});
Since mongodb objectId contatins creation date you can sort by id, descending and then use limit(1):
db.collection.find().sort( { _id : -1 } ).limit(1);
Note: i am not familiar with node.js at all, above command is mongo shell command and i suppose you can easy rewrite it to node.js.
Say I have companies collection. Below snippet gives me last document in the collection.
db.companies.find({},{"_id":1}).skip(db.companies.find().count()-1);
Code cannot rely on _id as it may not be on a specific pattern always if it's a user defined value.
Use sort and limit, if you want to use cursor :
var last = null;
var findCursor = collection.find({}).cursor();
findCursor.on("data", function(data) {
last = data;
...
});
findCursor.on("end", function(data) {
// last result in last
....
});