Why i can't use db.collection.countDocuments() - node.js

I want to get the number of documents in the 'image' collection.
my code is
var express = require('express');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var app = express();
app.set('view engine', 'ejs');
app.use(express.static(__dirname+'/public'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
dburl = "mongodb+srv://...";
mongoose.connect(dburl);
var db = mongoose.connection;
//...
var imageSchema = mongoose.Schema({
image_name:{type:String, required:true, unique:true}
});
var Image = mongoose.model('image', imageSchema);
var Dcount = db.image.countDocuments({});
but the console :
enter image description here

countDocuments() is available directly on model
You should be doing Image.countDocuments()
Image.countDocuments({}, function (err, count) {
if (err){
console.log(err)
}else{
console.log("Count :", count)
}
});

Related

schema is not a construktor [duplicate]

Not sure why this is happenening, tried removing all instances of new, switching to let from const ect. Can run site however when I run a post request via a html form, get an error on the line "const user = new UserSchema" ect. of TypeError: UserSchema is not a constructor.
const express = require('express');
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const bodyParser = require('body-parser');
let app = express();
let mongoDB = //hiding url for obvious reasons
mongoose.connect(mongoDB, { useNewUrlParser: true });
mongoose.Promise = global.Promise;
let db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
const UserSchema = new Schema({
name: String,
email: String
});
app.set('view engine', 'ejs');
app.use('/assets', express.static('assets'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.get('/', function(req,res){
res.render('landingPage');
});
app.post('/', function (req, res) {
const user = new UserSchema(req.body.name, req.body.email);
user.save()
.then(item => {
res.send("item saved to database");
})
.catch(err => {
res.status(400).send("unable to save to database");
});
});
app.listen(3000);
You have to assign the schema as a mongoose model.
var User= mongoose.model('user', UserSchema);

Invalid Namespace specified Mongoose save collection

I am creating an application using expressjs, mongoose and ejs template engine.
I am facing an below mentioned issue while saving collection:
{"message":"Invalid namespace specified 'ecommerce\";.roleresources'"}
This is my entry script app.js file:
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const expressLayout = require('express-ejs-layouts');
const config = require('./config');
const adminRoutes = require('./routes/admin');
const app = express();
// set the view engine to ejs
app.set('view engine', 'ejs');
app.set('views', 'views');
app.set('layout', 'layout/shop');
app.set("layout extractScripts", true)
app.use(bodyParser.urlencoded({ extended: false }));
app.use(expressLayout);
app.use(express.static(path.join(__dirname, 'public')));
app.use('/admin', adminRoutes);
mongoose.Promise = global.Promise;
mongoose
.connect(config.mongodb_uri, { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex:true } )
.then(result => {
console.log(result);
app.listen(config.port || 3000);
})
.catch(err => {
process.exit();
});
These are file config.js file:
const dotenv = require('dotenv');
dotenv.config();
module.exports = {
port:process.env.PORT,
mongodb_uri: process.env.MONGODB_URI
}
and this is my .env file:
PORT=3000
MONGODB_URI="mongodb://localhost:27017/ecommerce";
and model file is:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const roleResourceSchema = Schema({
name:{
type:String,
required:true
},
code:{
type:String,
required:true
},
url:{
type:String,
required:true
}
});
roleResourceSchema.index({name:1, code:1,url:1}, {unique:true});
module.exports = mongoose.model('RoleResource', roleResourceSchema);
and lastly my controller:
const RoleResource = require('../model/roleResource');
exports.getLogin = (req, res, next) => {
const resource = new RoleResource({
name:"All",
code:"all",
url:"*",
});
resource.save()
.then(data => {
res.send(data);
}).catch(err => {
res.status(500).send({
message: err.message
});
});
};
and if hard coded the mongodb url in my app.js then it's start working (modified app.js for working mongoose save)
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const expressLayout = require('express-ejs-layouts');
const config = require('./config');
const adminRoutes = require('./routes/admin');
const app = express();
// set the view engine to ejs
app.set('view engine', 'ejs');
app.set('views', 'views');
app.set('layout', 'layout/shop');
app.set("layout extractScripts", true)
app.use(bodyParser.urlencoded({ extended: false }));
app.use(expressLayout);
app.use(express.static(path.join(__dirname, 'public')));
app.use('/admin', adminRoutes);
mongoose.Promise = global.Promise;
mongoose
.connect("mongodb://localhost:27017/ecommerce", { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex:true } )
.then(result => {
console.log(result);
app.listen(config.port || 3000);
})
.catch(err => {
process.exit();
});
How can I dynamically use the mongo db url from my .env file
It took me a while to resolved mine, but i finally did.
In you .env file, remove the quotes in MONGODB_URI.
Check sample below
PORT=3000
MONGODB_URI=mongodb://localhost:27017/ecommerce
The reason you are having the error:
It's simply because of the way you are writing the MongoDB URI in the .env file i.e MONGODB_URI="mongodb://localhost:27017/ecommerce";
The dotEnv package would parse the value for MONGODB_URI as mongodb://localhost:27017/ecommerce";, notice the double-quote(") and the semi-colon(;) at the end, they are not supposed to be there and that is what is causing the error.
The fix:
All you need to do is remove the semi-colon and everything should be fine: MONGODB_URI="mongodb://localhost:27017/ecommerce"

Get data from mongoDB using node.js, connection works but no data is showing

So i have made an application using node.js and connected it to mongoDB, but no data is showing, it is simply showing and empty json data file []. The database name is sample_geospatial and the collection is named shipwrecks and all ip addresses are OK to connect with.
Why am i not succeeding with my task to show the data in the browser?
This is my app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var shipwrecksRouter = require('./routes/shipwrecks');
var app = express();
// Database connect with moongoose
var mongoose = require('mongoose');
mongoose.connect('mongodb+srv://gockzor:***********#cluster0-boypg.azure.mongodb.net/test?retryWrites=true&w=majority');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function (callback) {
console.log("Kopplingen lyckades!");
});
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({
extended: false
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/shipwrecks', shipwrecksRouter);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
module.exports = app;
This is my model
var mongoose = require('mongoose');
var WrecksSched = new mongoose.Schema({
recrd: String,
vesslterms: String,
feature_type: String,
chart: String,
latdec: Number,
londec: Number,
gp_quality: String,
depth: String,
sounding_type: String,
history: String,
quasou: String,
watlev: String,
coordinates: Array,
}, {
collection: 'shipwrecks'
});
module.exports = mongoose.model('ShipwrecksModel', WrecksSched);
This is my routes file
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var ShipwrecksModel = require('../models/ShipwrecksModel.js');
router.get('/', function (req, res, next) {
ShipwrecksModel.find(function (err, wrecks) {
if (err) return next(err);
else {
res.json(wrecks);
}
});
});
module.exports = router;
Putting it as an answer :
If you're seeing [] in the api response rather than an error -
then the issue could either be you're not able to connect to proper
collection name(if you're sure collection has data in it) or correct db where your collection exists.
So from your DB url :
'mongodb+srv://gockzor:***********#cluster0-boypg.azure.mongodb.net/test?retryWrites=true&w=majority'
You've got connected to test DB, So is that your DB where your collection shipwrecks exists ? If not the try to switch to actual DB after getting connected or replace test in url with actual DB name.
So by default you'll get an url w.r.t. to test db when you get it from Atlas mongoDB. So replace it on url once in all or you can switch it over the code after connecting to DB, using useDb function. Ex. :-
From code a basic way to switch DB ::
async function myDbConnection() {
const url = mongodb+srv://gockzor:***********#cluster0-boypg.azure.mongodb.net/test?retryWrites=true&w=majority';
try {
await mongoose.connect(url, { useNewUrlParser: true });
console.log('Connected Successfully')
mongoose.connection.useDb('myDB'); // Switching happens here..
/**
* Do some DB transaction with mongoose models as by now models has already been registered to created DB connection
*/
} catch (error) {
console.log('Error connecting to DB ::', error);
}
}
Or you can have something like this directly in url ::
const dbUrl = mongodb+srv://gockzor:***********#cluster0-boypg.azure.mongodb.net/myDB?retryWrites=true&w=majority'

mongoose findOne is not a function

I just tried to create simple login and registration form with mongodb version 3.2.21 because I've got Windows 7 with 32bit CPU so here is the code
var express = require('express');
var app = express();
var mongoose = require('mongoose');
var consolidate = require('consolidate');
var http = require('http').Server(app);
var io = require('socket.io')(http);
var multer = require('multer')
var upp = multer()
var bodyParser = require('body-parser')
var router = express.Router()
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(upp.array());
app.use(express.static('public'));
app.engine('html', consolidate.mustache);
app.set('view engine', 'html');
app.set('views', __dirname + '/views');
var mongoDB = 'mongodb://localhost/my_database';
mongoose.connect(mongoDB, {useNewUrlParser: true});
// Get Mongoose to use the global promise library
mongoose.Promise = global.Promise;
//Get the default connection
var db = mongoose.connection;
if(db){
console.log('connection')
}
//Bind connection to error event (to get notification of connection errors)
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
var Schema = mongoose.Schema;
var SomeModelSchema = new Schema({
username: String,
password: String
});
var SomeModel = mongoose.model('SomeModel', SomeModelSchema );
var newuser = new SomeModel();
app.get('/', function(req, res){
res.render('mainpage')
})
app.get('/reg', function(req, res){
res.render('reg')
})
app.post('/reeg', function(req,res){
newuser.username = req.body.username;
newuser.password = req.body.password;
newuser.save(function (err, savedObject){
if (err){
console.log(err)
}else{
console.log(savedObject);
res.sendFile(__dirname + '\\views\\mainpage.html')
}})
});
app.post('/login', function(req,res){
var userr = req.body.usernamee
var pass = req.body.passwordd
newuser.findOne({username: userr, password: pass}).exec(),
function(err,obj){
if(err) {return res.status(404)
}else if(!obj){
res.send('notregistered')
}if(obj){
res.send('hey' + userr)
}
}})
http.listen('8080')
and this is giving me this error
So what is problem here? I am not using express router yet and this code is in one file
newuser is not a model, it's an instance of SomeModel - list of methods here
findOne is method of model - SomeModel list of methods here
so replace: newuser.findOne to SomeModel.findOne
I've rewritten overall code for better readability, async/await features, with object destructuring examples and etc best practices:
'use strict';
const path = require('path');
const http = require('http');
const express = require('express');
const socketIO = require('socket.io');
const bodyParser = require('body-parser');
const consolidate = require('consolidate');
// DB connection
const mongoose = require('mongoose');
const connectionString = 'mongodb://localhost/my_database';
mongoose.Promise = global.Promise;
mongoose
.connect(connectionString, {useNewUrlParser: true})
.then(() => {
console.log('Connection to database established');
})
.catch(error => {
console.error('MongoDB connection error:', error.message);
process.exit(-1);
});
// End of: DB connection
// Defining DB schemas and models
const Schema = mongoose.Schema;
const UserSchema = new Schema({
username: String,
password: String
});
const User = mongoose.model('User', UserSchema);
// End of: Defining DB schemas and models
// Initial app configuration
const app = express();
const server = http.Server(app);
const io = socketIO(server);
app.engine('html', consolidate.mustache);
app.set('view engine', 'html');
app.set('views', path.join(__dirname, 'views'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static('public'));
// End of: Initial app configuration
// App route handlers
app.get(
'/',
(req, res) => {
res.render('mainpage');
});
app.get(
'/reg',
(req, res) => {
res.render('reg');
});
app.post(
'/reg',
async (req, res) => {
try {
const {username, password} = req.body;
const user = await User.create({username, password});
console.log('Created user:', user);
res.sendFile(path.join(__dirname, 'views', 'mainpage.html'));
}
catch (error) {
res.status(500).send(error.message);
}
});
app.post(
'/login',
async (req, res) => {
try {
const {username, password} = req.body;
const user = await User.findOne({username, password}).select('-password').lean();
if(!user) {
res.send('User: ' + username +' not registered');
return;
}
res.send('hey ' + username);
}
catch (error) {
res.status(500).send(error.message);
}
});
// End of: App route handlers
// Binding http listener to port
server.listen('8080');
Notice: lean is method of query manual here
Fix Your login form:
<form action="/login" method="POST">
<input type="text" placeholder="username" name="username">
<input type="password" placeholder="pass" name="password">
<button type="submit">Login</button> <br/>
or <strong>Sign Up</strong>
</form>
P.S. Write in comments if something will go wrong.

Mongodb db.get('usercollection') not working corretly

Issue is that db is not working properly
app.js
var express = require('express');
var path = require('path');
var http = require('http');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongo = require('mongodb');
var monk = require('monk');
var db = monk('localhost:27017/nodetest1');
var routes = require('./routes');
var users = require('./routes/users');
var app = express.createServer();
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
app.use(function(req,res,next){
req.db = db;
next();
});
routes/index.js
exports.index = function(req, res){
var db = req.db;
var collection = db.get('usercollection');
collection.find({},{},function(e,docs){
res.render('userlist', {
"userlist" : docs
});
});
};
When I run userlist I get an error on line db.get('usercollection'). When I log req.db it is undefined.
How to resolve it?
you can directly use your db module in the index.js file
module.exports = (function() {
'use strict';
var apiRoutes = express.Router();
var Server = mongo.Server;
var Db = mongo.Db;
var BSON = mongo.BSONPure;
function connexionDataBase(callback){
var server = new Server('your db URL', 27017, {auto_reconnect: true});
db = new Db('you Db', server);
db.open(function(err, db) {
if(!err) {
console.log("Connected to 'you Db' database");
callback(err,db);
}
else{
console.log("not Connected to 'you Db' database");
callback(err,db);
}
});
})();
and in your app.js your can redirect the app routes to index.js :
var express = require('express');
var index = require('./index');
var app = express();
app.use('/index',index);

Resources