Node mongodb driver can insert, count, but find - node.js

I am migrating an existing app to mongodb,
I have this code mostly found on the node native mongodb driver site.
var fs = require('fs-extra');
var MongoClient = require('mongodb').MongoClient;
const mongoConfig = JSON.parse(fs.readFileSync("./configuration/mongo.json", "utf-8").toString());
const assert = require('assert');
const insertDocuments = function(db, callback) {
// Get the documents collection
const collection = db.collection('documents');
// Insert some documents
collection.insertMany([
{a : 1}, {a : 2}, {a : 3}
], function(err, result) {
assert.equal(err, null);
assert.equal(3, result.result.n);
assert.equal(3, result.ops.length);
console.log("Inserted 3 documents into the collection");
callback(result);
});
};
const findDocuments = function(db, callback) {
// Get the documents collection
const collection = db.collection('documents');
// Find some documents
collection.find({}).toArray(function(err, docs) {
assert.equal(err, null);
console.log("Found the following records");
console.log(docs)
callback(docs);
});
};
function initDb() {
var uri = "mongodb://" + mongoConfig.user + ":" + mongoConfig.pass + "#" + mongoConfig.host + ":" + mongoConfig.port;
MongoClient.connect(uri, {auth: {user: mongoConfig.user, password: mongoConfig.pass}, authSource: mongoConfig.dbname}, function (err, client) {
if (err) {
console.error(err);
}
const db = client.db('test');
insertDocuments(db, function() {
findDocuments(db, function() {
client.close();
});
});
}
initDb();
Then i get the following output in the console :
Inserted 3 documents into the collection
Found the following records
[]
Using Robomongo from the same computer to the same server using same credentials, i am able to see and edit the datas.
the insert is working fine, as i am writing this i have a dozen of test documents inserted this way.
But find allways return an empty array.
However, using count instaed of toArray returns the corret value.
I am using :
"mongodb": "^3.0.5",
From my package.json
What am i missing pls ?

Related

Connecting to MongoDB Successfully, But Having Issues with `getCollection()`

I am writing some tests for a Node/Mongo project, and in one of my tests I need to connect to the database, and then pull a document from my jobs collection. However, I am running into an issue. I can connect to the database successfully, but then get an error on my findOne(). The specific error is:
TypeError: db.getCollection is not a function
Here is the code:
const MongoClient = require('mongodb').MongoClient;
const url = 'mongodb://localhost:27017';
const dbName = 'sample_db';
// Create a new MongoClient
const client = new MongoClient(url);
client.connect(async function (err) {
assert.equal(null, err);
console.log("Connected successfully to server"); // I see this in the console
const db = await client.db(dbName);
let savedJobResult = await db.getCollection("jobs").findOne({
"name": "Agenda Job Test"
});
console.log('savedJobResult: ', savedJobResult);
client.close();
});
What am I missing here?
Try this query
let savedJobResult = await db.collection("jobs").findOne({
"name": "Agenda Job Test"
});
change getCollection to collection
const insertDocuments = function(db, callback) {
// Get the documents collection
const collection = db.collection('documents');
// Insert some documents
collection.insertMany([
{a : 1}, {a : 2}, {a : 3}
], function(err, result) {
assert.equal(err, null);
assert.equal(3, result.result.n);
assert.equal(3, result.ops.length);
console.log("Inserted 3 documents into the collection");
callback(result);
});
}

Uploading a doc file Directly in Mongodb

I want to save and retrieve a Word doc and PDF file with a size of 1 MB, directly in MongoDB with Node.js. How can I do this is there any article explain about it or can some one help me on this.
Here is the standalone node js code to save the file as binary data in MongoDB. As the maximum file size is 1MB, you can save it in normal collection rather than GridFs.
This can be extended to run as web apps using "express" or "hapi" frameworks. You may need to refer the respective tutorial for that.
Save the file as binary data in MongoDB:-
Note: I have the sample file in "docs" directory. So, I have prefixed it with docs (i.e. "/docs/testplan.docx"). You can remove that if you don't need it.
var MongoClient = require('mongodb').MongoClient;
var Binary = MongoClient.Binary;
var fs = require('fs');
var assert = require('assert');
var url = 'mongodb://localhost:27017/test';
var binaryFileData = fs.readFileSync(__dirname + "/docs/testplan.docx");
var insertDocument = function(db, callback) {
db.collection('file_save').insertOne( {
"fileName" : "testplan.docx",
"fileData" : binaryFileData
}, function(err, result) {
assert.equal(err, null);
console.log("Inserted a document into the collection.");
callback();
});
};
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
insertDocument(db, function() {
console.log("Closing the database connection...")
db.close();
});
});
Read the file data and save it to disk:-
var MongoClient = require('mongodb').MongoClient;
var Binary = MongoClient.Binary;
var fs = require('fs');
var assert = require('assert');
var url = 'mongodb://localhost:27017/test';
var findDocument = function (fileName, db, callback) {
db.collection('file_save').findOne({"fileName" : fileName }, function (err, document) {
assert.equal(null, err);
console.log(document.fileName);
fs.writeFileSync("testplan_out.docx", document.fileData.buffer);
console.log("File has been written to disk");
callback();
});
};
MongoClient.connect(url, function (err, db) {
assert.equal(null, err);
findDocument("testplan.docx", db, function () {
db.close();
});
});
that works perfectly alright! But I'm trying to upload the document from the POSTMAN and I'm developing my project with MEAN stack.
//document-model.js
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var documentSchema = {
docFile: {
type: String
}
};
mongoose.model('FileDocument', documentSchema);
//document-route.js
var express = require('express'),
documentRoute = express.Router(),
document = require('../controllers/document-controller');
documentRoute.post('/upload', document.uploadDocument);
module.exports = documentRoute;
//document-controller.js
var document = {
uploadDocument: function (req, res) {
var fileDocument = new FileDocument({
docFile: req.body.docFile
});
fileDocument.save(function (err, result) {
if (err) {
res.status(500).send(err);
} else {
res.status(200).send('Document Uploaded Successfully');
}
});
}
};
I was trying in this way but it is not uploading to mongodb the result is gives in the mongo shell.
{ "_id" : ObjectId("59693872b8b83f42b42a3b9f"), "docFile" : "", "__v" : 0 }

Fire callback after cursors foreach function is done?

i am using NodeJS to iterate over a large product collection. MongoDb native driver is used. Everything is fine but i want to write a footer line to a file after all documents are processed. How can i accomplish this?
var MongoClient = require('mongodb').MongoClient
var assert = require('assert');
var filename = '/tmp/' + feed.outputFilename;
fs.writeFileSync(filename, feed.header, feed.encoding, function(err) {
if(err) throw err;
});
var url = process.env.DB_HOST;
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
var collection = db.collection('products');
var cursor = collection.find({ "catalog": "electronics"}, { "batchSize": 1,fields: {} }).forEach(function(product) {
if(product != null) {
var child = workers[Math.floor(Math.random()*workers.length)];
var data = {};
data.product = product;
data.feed = feed;
child.send(data);
}
}, function(err) {
assert.equal(null, err);
db.close();
});
// This doens't work for me (Error: Connot read property 'on' of undefined)
/*cursor.on('end', function() {
fs.appendFile('/tmp/' + filename, feed.footer, function(err) {
if(err) throw err;
});
db.close();
})*/
});
Possibly what could be happening here is that the value returned from your call to forEach is being assigned into the cursor var.
Try assigning the value returned from the find into the cursor var and calling your forEach as cursor.forEach and cursor.on later.

Callback function running unexpectedly

There is a small code i have written below and issue is explained within comments. Problem is with the bold callback function while creating the collection. There is an error while creating the collection and the message should be displayed as soon as the main function for creating the collections is ending but message appears randomly as seen in the output below:
It is called unexpected on line marked with question mark. I am running this js file on node.js and mongoDB environment.
Thanks.
var mongo = require("mongodb");
var Db = mongo.Db;
var mongoC = mongo.MongoClient;
var assert = require('assert');
mongoC.connect("mongodb://localhost:27017/social", {
native_parser: true
}, function (err, db) {
if (!err) {
console.log("We are Connected!\n");
//creating the Collection
db.createCollection("node", {
strict: true
}, function (err, coll) {
if (!err) {
console.log("*********Collection Created Succesfully*********");
console.log("Collection created Successfully\n" + JSON.stringify(coll) + "\n-------------------\n");
}
else{
console.log("Cannot create Collection because " + err);
}
});
//Collection created now
console.log("*********************************inserting documents in the selected collection***********************");
var coll = db.collection('node');
var doc1 = {"name":"doc1","age":26};
var manydocs = [{"name":"doc2","age":45},{"name":"doc3","age":19}];
//coll.insert(doc1,{w:1},function(err,result){if(err){console.log("Error while inserting doc1 " + err);}else{console.log(result);}});
//coll.insert(manydocs,{w:1},function(err,result){if(err){console.log("Error while inserting manydocs " + err);}});
console.log("***************************documents are now updated successfully***********************************");
console.log("*******************Now let us update the documents*******************");
var query = {"name": "doc1"};
var update= {$set : {"age":86}};
//coll.update(query,update,function(err,result){if(!err){console.log(result + "'s age has been successfully update to " + result);}});
console.log("***************Docments updated");
console.log("*******************Querying the items**************************");
coll.find().each(function(err,myDoc){console.dir(myDoc);console.dir("hey");});
//coll.findOne(query,function(err,result){});
var stream = coll.find(query).stream();
stream.on("data",function(item){console.log(item._id);});
stream.on("end",function(){});
}
else {
console.log("Cannot connect because : " + err);
}
});
Below is the output.
We are Connected!
*********************************inserting documents in the selected collection***********************
***************************documents are now updated successfully***********************************
*******************Now let us update the documents*******************
***************Docments updated
*******************Querying the items**************************
Cannot create Collection because Error: Collection node already exists. Currently in strict mode.
You should work on node collection inside the db.createCollection's callback:
UPDATE: run this code:
var mongo = require("mongodb");
var Db = mongo.Db;
var mongoC = mongo.MongoClient;
var assert = require('assert');
mongoC.connect("mongodb://localhost:27017/social", {
native_parser: true
}, function (err, db) {
if (!err) {
console.log("We are Connected!\n");
//creating the Collection
db.createCollection("node", {
strict: true
}, function (err, coll) {
if (!err) {
console.log("*********Collection Created Succesfully*********");
console.log("Collection created Successfully\n" + JSON.stringify(coll) + "\n-------------------\n");
//Collection created now
console.log("*********************************inserting documents in the selected collection***********************");
var doc1 = {
"name": "doc1",
"age": 26
};
var manydocs = [{
"name": "doc2",
"age": 45
}, {
"name": "doc3",
"age": 19
}];
//coll.insert(doc1,{w:1},function(err,result){if(err){console.log("Error while inserting doc1 " + err);}else{console.log(result);}});
//coll.insert(manydocs,{w:1},function(err,result){if(err){console.log("Error while inserting manydocs " + err);}});
console.log("***************************documents are now updated successfully***********************************");
console.log("*******************Now let us update the documents*******************");
var query = {
"name": "doc1"
};
var update = {
$set: {
"age": 86
}
};
//coll.update(query,update,function(err,result){if(!err){console.log(result + "'s age has been successfully update to " + result);}});
console.log("***************Docments updated");
console.log("*******************Querying the items**************************");
coll.find().each(function (err, myDoc) {
console.dir(myDoc);
console.dir("hey");
});
//coll.findOne(query,function(err,result){});
var stream = coll.find(query).stream();
stream.on("data", function (item) {
console.log(item._id);
});
stream.on("end", function () {});
} else {
console.log("Cannot create Collection because " + err);
}
});
} else {
console.log("Cannot connect because : " + err);
}
});

How to rename/alias field(s) while fetching it from MongoDB through query using MongoDB-Node.JS native drive?

Consider the following code, which I am using to fetch the data from my local MongoDB server.
var Db = require('mongodb').Db,
MongoClient = require('mongodb').MongoClient,
Server = require('mongodb').Server,
ReplSetServers = require('mongodb').ReplSetServers,
ObjectID = require('mongodb').ObjectID,
Binary = require('mongodb').Binary,
GridStore = require('mongodb').GridStore,
Code = require('mongodb').Code,
BSON = require('mongodb').pure().BSON,
assert = require('assert');
var db = new Db('test', new Server('localhost', 27017));
db.open(function(err, db) {
db.createCollection('simple_limit_skip_find_one_query', function(err, collection) {
assert.equal(null, err);
collection.insert([{a:1, b:1}, {a:2, b:2}, {a:3, b:3}], {w:1}, function(err, result) {
assert.equal(null, err);
collection.findOne({a:1}, {fields:{b:1}}, function(err, doc) {
// I got the read document in the object 'doc'
});
});
});
});
Now, I want to rename a field name while retrieving only (not in the DB), for example with the above code, I have a field named b in the returned object doc I want it to be baseID instead of b
Is there any way to do it?
Note: I cannot take action on the retrieved object doc to rename field like JSON key renaming. I want it to be queried and MongoDB will the same.
Use aggregate framework of MonogDB (But you need to upgrade the MongoDB server instance to >= 2.1).
The following is the soultion for the above example
var Db = require('mongodb').Db,
MongoClient = require('mongodb').MongoClient,
Server = require('mongodb').Server,
ReplSetServers = require('mongodb').ReplSetServers,
ObjectID = require('mongodb').ObjectID,
Binary = require('mongodb').Binary,
GridStore = require('mongodb').GridStore,
Code = require('mongodb').Code,
BSON = require('mongodb').pure().BSON,
assert = require('assert');
db.open(function (err, db) {
if (err) console.dir(err);
db.createCollection('simple_limit_skip_find_one_query', function (err, collection) {
if (err) console.dir(err);
collection.insert([{ a: 1, b: 1 }, { a: 2, b: 2 }, { a: 3, b: 3}], { w: 1 }, function (err, doc) {
if (err) console.dir(err);
collection.aggregate([
{ $project: {
a: 1,
_id:0,
baseID: "$b"
}
}
], function (err, doc) {
if (err) console.dir(err);
console.log(doc);
});
});
});
});
Output:
[ { a: 1, baseID: 1 },
{ a: 2, baseID: 2 },
{ a: 3, baseID: 3 }]

Resources