Cannot read collection from MongoDB - mongodb

So, I'm trying to connect a mongo database and it's already connected. But my issue is that I can't read collection from mongo in another file, it says: db.collection is not a function.
So this is my db.js file:
const { MongoClient } = require('mongodb');
let connection_string = 'mongodb+srv://username:password#cluster0.3ctoa.mongodb.net/myFirstDatabase?retryWrites=true&w=majority';
let client = new MongoClient(connection_string, {
useNewUrlParser: true,
useUnifiedTopology: true
});
let db = null
export default () => {
return new Promise((resolve, reject) =>{
if (db && client.isConnected()){
resolve(db)
}
client.connect(err => {
if(err){
reject("Error in connection " + err)
}
else{
console.log("Success")
db = client.db("posts")
resolve(db)
coll = db.collection('posts');
}
});
})
};
The thing is I got successfully connected to a database, but when I try to work with collections it says they are not functions.
This is my second file where I already imported connect from db.js, so here is what I want to do:
app.post('/posts', async (req,res)=>{
let db = connect();
let posts = req.body;
let result = await db.collection('posts').insertOne(posts);
})
Here is the exact error I'm getting:
UnhandledPromiseRejectionWarning: TypeError: db.collection is not a function
at _callee$ (C:\Users\Jan\Desktop\Webshop\posts\src\/index.js:21:33)
at tryCatch (C:\Users\Jan\Desktop\Webshop\posts\node_modules\regenerator-runtime\runtime.js:63:40)
at Generator.invoke [as _invoke] (C:\Users\Jan\Desktop\Webshop\posts\node_modules\regenerator-runtime\runtime.js:294:22)
at Generator.next (C:\Users\Jan\Desktop\Webshop\posts\node_modules\regenerator-runtime\runtime.js:119:21)
at asyncGeneratorStep (C:\Users\Jan\Desktop\Webshop\posts\src\index.js:11:103)
at _next (C:\Users\Jan\Desktop\Webshop\posts\src\index.js:13:194)
at C:\Users\Jan\Desktop\Webshop\posts\src\index.js:13:364
at new Promise (<anonymous>)
at C:\Users\Jan\Desktop\Webshop\posts\src\index.js:13:97
at C:\Users\Jan\Desktop\Webshop\posts\src\/index.js:16:1

Related

MongoDB using with NodeJS

I want to connect mongodb to nodejs.
I succeed to connect mongodb to nodejs but I can't access to mongodb Collection (test collection).
How can I use collection in my code?
BELOW MY CODE
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/test';
var db;
MongoClient.connect(url, function (err, database) {
if (err) {
console.error('MongoDB 연결 실패', err);
return;
}else{
console.log("DB연결 성공")
}
db = database;
});
var movies = db.Collection('test');
movies.insert();
ERROR CODE
TypeError: Cannot read properties of undefined (reading 'Collection')
at Object.<anonymous> (C:\Users\USER\Desktop\test\mongodbtest.js:15:17)
at Module._compile (node:internal/modules/cjs/loader:1126:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1180:10)
at Module.load (node:internal/modules/cjs/loader:1004:32)
at Function.Module._load (node:internal/modules/cjs/loader:839:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:17:47
You are trying to access the db instance sequentially, but the code in the callback will be executed after the var movies = db.Collection('test'); line is called, so the variable won't be set.
You can either move the insert inside the callback:
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/test';
MongoClient.connect(url, function (err, database) {
if (err) {
console.error('MongoDB 연결 실패', err);
return;
} else {
console.log('DB연결 성공');
}
var movies = database.Collection('test');
movies.insert();
});
Or use async await:
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/test';
const connectDb = async () => {
try {
return await MongoClient.connect(url)
} catch (err) {
console.error('MongoDB 연결 실패', err);
}
}
connectDb()
.then((db) => {
var movies = db.Collection('test');
movies.insert();
})

mongo db transaction with multiple collection not working

the following function is supposed to do:
save the project into collection 'project_list'
push the uuid of the new project to a client in the collection 'client_list'
with transaction enabled, if anything goes wrong (such as the client id is given in the new project JSON object does not exist in the collection 'client_list'), then both step1 and step2 will be canceled.
noticed that the code is giving the client_id as 'invalid-uuid' to updateOne which will not add the project uuid to the client because the client_id does not exist in the collection but the new project is saved into collection 'project_list' with or without me doing commitTransaction.
I was reading this https://mongoosejs.com/docs/transactions.html which suggest me to abort the transaction by calling await session.abortTransaction(); but i dont know how to implement it.
thanks in advance.
transactionCreateProject: async function (newProjectJson) {
const mongoConnectConfig = {useNewUrlParser: true, useUnifiedTopology: true};
await mongoose.connect(CONSTANTS.ADMIN_MONGO_URL, mongoConnectConfig)
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'))
db.once("open", function (callback) {
console.log("Connection Succeeded")
});
let project = mongoose.model('project', mongooseProjectSchema)
let client = mongoose.model('client', mongooseClientSchema)
const session = await mongoose.startSession();
session.startTransaction();
try {
console.log(newProjectJson.clientUUID)
let newProjectMongooseObject = new project()
for (let i = 0; i < Object.keys(newProjectJson).length; i++){
// assigning the attributes of new project to mongoose object
newProjectMongooseObject[Object.keys(newProjectJson)[i]] = newProjectJson[Object.keys(newProjectJson)[i]]
}
newProjectMongooseObject['createdAt'] = dateObject.toISOString();
let saveRes = await newProjectMongooseObject.save()
let addProjectToClientRes = await clientMongooseModel.updateOne({ 'uuid': "invalid-uuid"}, {$push: {'projects': { projectID: newProjectJson.uuid}}})
}
catch (e) {
console.log(e)
return null
}
finally {
console.log("in finally, session ending")
session.endSession();
}
return null
},

unable to use $merge on another remote database

I am trying to move documents based on last update time into another remote db.
Currently trying to use $merge to implement the same.
But new database is created on same local connection and not on remote connection.
LOCAL_DB_NAME.aggregate([
{ $merge: { into: { db: "REMOTE_DB_NAME", coll:"COLLECTION_NAME" } }},
]).toArray();
Connection Initialization code:
const MongoClient = require('mongodb').MongoClient;
const url = 'mongodb://xxx:27017';
const dbName = 'local';
const url2 = 'mongodb://xxx:27017';
const dbName2 = 'remote';
var dbClient,dbClientRemote;
MongoClient.connect(url, async function(err, client) {
if(err){
console.log("->", err)
return
}
console.log("Connected successfully to server");
const db = client.db(dbName);
dbClient = client;
MongoClient.connect(url2, async function(err2, client2) {
if(err2){
console.log("->", err2)
return
}
console.log("Connected successfully to server2");
const db2 = client2.db(dbName2);
dbClientRemote = client2;
});
});
It's not possible. You can move into [different DB] collection only for the same instance (Standalone / Replica set).

Retrieving data from mlab heroku

I followed a tutorial to learn Express.js App that performs basic CRUD operations from MongoDB. All operations created locally works fine.
As a next step (not in the tutorial), I needed to integrate mLab provided by Heroku for MongoDB in order to push the app to Heroku.
Now, I need to make necessary changes on the mongoose connection since I am moving from a local database to mLab. I made necessary changes but now the app throws an error.
complaintController.js (class to get request and use the model)
Complaint = require('./complaintModel');
exports.index = function (req, res) {
Complaint.get(function (err, complaints) { //GET function
if (err) {
res.json({
status: "error",
message: err,
});
}
res.json({
status: 200,
message: "Complaints retrieved successfully",
data: complaints
});
});
};
complaintModel.js (local MongoDB this works fine)
var mongoose = require('mongoose');
var complaintSchema = mongoose.Schema({
name: {
type: String,
required: true
},
});
// Export Complaint model
var Complaint = module.exports = mongoose.model('complaint', complaintSchema);
module.exports.get = function (callback, limit) {
Complaint.find(callback).limit(limit);
}
complaintModel.js ( connecting to mLab throws error)
var mongoDB = "MongoDB URI";
var connection = mongoose.createConnection(mongoDB,
{
User: 'username',
Password: 'pass'
});
var Complaint;
connection.on('open', function() {
console.log('connection established!!!');
Complaint = module.exports = connection.model('master_complaint', complaintSchema);
module.exports.get = function (callback, limit) {
Complaint.find(callback).limit(limit);
}
});
Here I get the following error when I give a get request I understood there is an export issue of Complaint Module but any suggestion or idea will be helpful.
TypeError: Complaint.get is not a function
at exports.index (R:\Workings\PersWork\web\webpack-demo\controller\complaintController.js:6:15)
at Layer.handle [as handle_request] (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\layer.js:95:5)
at next (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\layer.js:95:5)
at R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\index.js:281:22
at Function.process_params (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\index.js:335:12)
at next (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\index.js:275:10)
at Function.handle (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\index.js:174:3)
at router (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\index.js:47:12)
at Layer.handle [as handle_request] (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\index.js:317:13)
at R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\index.js:284:7
at Function.process_params (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\index.js:335:12)
at next (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\index.js:275:10)
at jsonParser (R:\Workings\PersWork\web\webpack-demo\node_modules\body-parser\lib\types\json.js:110:7)
From what I can see in the code. complaintController will be used by the express.js router, Am I correct?
I also see in the complaintModel.js is that the get function you've exported requires 2 parameters which are a filter & a limit. But in the Controller file you're not providing any of those arguments at all.
I haven't tested this myself yet but try changing your complaintModel.js to this
var mongoose = require("mongoose");
var complaintSchema = mongoose.Schema({
name: {
type: String,
required: true
}
});
var Complaint = mongoose.model("master_complaint", complaintSchema);
// Exports the get function
module.exports.get = function(filter, limit, callback) {
var mongoDB = "MongoDB URI";
var connection = mongoose.createConnection(mongoDB, {
User: "username",
Password: "pass"
});
connection.on("open", function() {
console.log("connection established!!!");
Complaint.find(filter)
.limit(limit)
.exec()
.then(results => {
callback(undefined, results)
})
.catch(err => {
console.log(err);
callback("ERROR: Can't query the collection", undefined)
});
});
};
And change the complaintController.js to the following
var Complaint = require("./complaintModel");
module.exports.index = function(req, res) {
var params = req.query;
const filter = params.filter;
const limit = params.limit;
Complaint.get(
filter,
limit,
(err,
complaints => {
if (err) {
res.json({
status: "error",
message: err
});
} else {
res.json({
status: 200,
message: "Complaints retrieved successfully",
data: complaints
});
}
})
);
};

ES6 promise will not work always with mongodb replication set

I did follow How to use MongoDB with promises in Node.js?. The answer 4 by(https://stackoverflow.com/users/5371505/pirateapp), works well with regular mongodb server. But it will not work always with a mongoDB replication set.
const mongodb = require('mongodb');
const MongoClient = mongodb.MongoClient;
// the url talking to replicaSet does not work, while the url with regular mongoDB sever seems working for me.
// const url = 'mongodb://alexlai:alex1765#arch16GMongo01.yushei.me:27017,arch16GMongo02.yushei.me:27017,arch16GMongo03:27017/YuShei?replicaSet=odroid00&connectTimeoutMS=300000';
url = 'mongodb://172.16.1.108/YuShei';
let db = {
open : open,
}
function open(){
return new Promise((resolve, reject)=>{
MongoClient.connect(url, (err, db) => {
if (err) {
reject(err);
} else {
resolve(db);
}
});
});
}
function close(db){
if(db){
db.close();
}
}
// module.exports = db;
// const db = require('./mongoDBServer.js');
const assert = require('assert');
const collectionName= 'yuTsaiLpr20161021'; // a collection contains 500 docs.
// this will hold the final array taht will be sent to browser
// a global variable will be declared with upper camel
let Array = [];
// this will hold database object for latter use
let Database = '';
// global query string and projection
let Query = {};
let Projection = {};
let Collection ={};
let checkoutCarPromise = new Promise((resolve, reject)=>{
Database = null;
db.open() // no ';' semi-column this is a promise, when successful open will be reolved and return with db object, or reject
.then((db)=>{
Database = db; // save it globally
return db.collection(collectionName);
})
.then((collection)=>{
if(collection == 'undefined') reject('collection not found!!');
Collection = collection; //seave it globally
return(collection);
})
.then((collection)=>{
return collection.find(); // return a cursor
})
.then((cursor)=>{
return cursor.toArray();
})
.then((array)=>{
console.log('array[499]: ', array[499]);
Array.push(array[499]);
})
.then(()=>{ // reread to find this car
return Collection.find({plateText:{$regex: /8920/}});
})
.then((cursor)=>{
return cursor.toArray();
})
.then((array)=>{
Array.push(array);
resolve(Array);
})
})
.catch((err)=>{
return(err);
console.error('the checkoutCarPromiserror is: ', err);
})
Promise.all([checkoutCarPromise]).then(results => {
console.log('checkoutCarPromise last resolve value: ', results[0]);
console.log('Array: ', Array);
Database.close();
})
// this will get you more infos about unhandled process
process.on("unhandledRejection", (reason) => {
console.log(reason)
})