How to get data from existing MongoDB database? - node.js

I have a database on mlab and now I was starting a new Project and trying to simply get data from there.
The Database has only one collection called Article.
On my Node js project, using Mongoose, I created the Model for it:
var mongoose = require('mongoose');
var articleSchema = new mongoose.Schema({
title: { type: String, required: true },
body: { type: String }
});
var Article = mongoose.model('Article', articleSchema);
module.exports = Article;
The in my controller I just did this:
Article.find({}, function (err, articles) {
res.send(articles);
});
I should receive more than 300 articles but the response is just an empty Array.
I was wondering if I need to run a few more command in order to connect to the db correctly, but I don't know it...

If you want to fetch on an existing Article collection:
var articleSchema = new mongoose.Schema({
title: { type: String, required: true },
body: { type: String }
}, { collection : 'Article' });

Related

Autoincrement with Mongoose

I'm trying to implement an autoicremental user_key field. Looking on this site I came across two questions relevant for my problem but I don't clearly understand what I should do. This is the main one
I have two Mongoose models, this is my ProductsCounterModel.js
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var Counter = new Schema({
_id: {type: String, required: true},
sequence_value: {type: Number, default: 0}
});
module.exports = mongoose.model('products_counter', Counter);
and this is the Mongoose model where I try to implement the auto-increment field:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var products_counter = require('./ProductsCounterModel.js');
var HistoricalProduct = new Schema({
product_key: { type: Number },
class: { type: String },
brand: { type: String },
model: { type: String },
description: { type: String }
});
HistoricalProduct.pre("save", function (next) {
console.log("first console log:",products_counter);
var doc = this;
products_counter.findOneAndUpdate(
{ "_id": "product_key" },
{ "$inc": { "sequence_value": 1 } },
function(error, products_counter) {
if(error) return next(error);
console.log("second console log",products_counter);
doc.product_key = products_counter.sequence_value;
next();
});
});
module.exports = mongoose.model('HistoricalProduct', HistoricalProduct);
Following the steps provided in the above SO answer I created the collection products_counter and inserted one document.
The thing is that I'm getting this error when I try to insert a new product:
"TypeError: Cannot read property 'sequence_value' of null"
This are the outputs of the above console logs.
first console log output:
function model (doc, fields, skipId) {
if (!(this instanceof model))
return new model(doc, fields, skipId);
Model.call(this, doc, fields, skipId);
}
second console log:
Null
can you see what I'm doing wrong?
You can run following line in your middleware:
console.log(products_counter.collection.collectionName);
that line will print products_counters while you expect that your code will hit products_counter. According to the docs:
Mongoose by default produces a collection name by passing the model name to the utils.toCollectionName method. This method pluralizes the name. Set this option if you need a different name for your collection.
So you should either rename collection products_counter to products_counters or explicitly configure collection name in your schema definition:
var Counter = new Schema({
_id: {type: String, required: true},
sequence_value: {type: Number, default: 0}
}, { collection: "products_counter" });

Mongoose validation and GridsFS

I would like add a mongoose validation in my code but I don't have a ".save method" in my code. It's because I use GridFS who to manage the save in the Database.
My question is simple. How get I a mongoose error with a other method.
This is a example of code.
First part, the schema
var mySchema = new Schema({
name: {
type: String,
required: true
},
color: {
type: String,
required: true
}
});
mongoose.model('mySchema', mySchema);
Second Part, the JS Code
Normally, you have this code.
var mySchema = mongoose.model('mySchema');
function upload(req, res){
var name = req.body.name;
var color = req.body.color;
var myUpload = new MySchema({
name: name,
color: color
})
myUpload.save(function(err){
if(err){
console.log(err)
}
})
}
But me, I don't have this code because GridFS manage all. So, how catch a error while schema execution if i don't have this code, but gridFS ?

Data seeded with Mongoose not being saved in MongoDB

I'm trying to add some data to MongoDB using Mongoose, but I'm having trouble getting that data to save to my database. I'm following this tutorial on YouTube (~11 min), but I think the video might be using a different version of Mongoose.
Basically, I have a Product schema defined in a separate JS file, and I'm running a file called productSeeder.js by running node productSeeder.js in terminal with the Mongo daemon running. When I switch to the correct database and type db.products.find() into the Mongo shell, nothing is returned to me.
My productSeeder.js file:
var Product = require('../models/product');
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/shopping');
var products = [
new Product({
imagePath: 'images/dummy.png',
price: 9,
title: 'a title',
desc: 'some text'
}),
new Product({
imagePath: 'images/dummy.png',
price: 5,
title: 'a title',
desc: 'some text'
})
];
var done = 0;
for (var i = 0; i < products.length; i++) {
products[i].save(function(err, result) {
if (err) {
console.log(err);
return;
};
done++;
if (done == products.length) {
mongoose.disconnect();
};
});
};
My product.js file:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var schema = new Schema({
imagePath: {type: String, required: true},
price: {type: Number, required: true},
title: {type: String, required: true},
desc: {type: String, required: true}
});
module.exports = mongoose.model('Product', schema);
Thanks so much, and happy holidays!
Do you know if Mongoose has successfully been connected before you try to save the Products?
One thought could be that since the Db access is async, you're trying to save off items before the connection exists.
You could pass a callback to your connection or use an event listener and wrap your save functions in the connection callback.
mongoose.connection.on('connected', function(){
//save products here
});
I've read of a few cases of Mongoose failing to save without error.
Edit: might be better to listen for .on('open') instead (mongoose docs).

MongoError: E11000 duplicate key error

i'm making a simple blog app using nodejs + express, i can add first post without a problem but when i try to add second post i got his error { MongoError: E11000 duplicate key error collection: restful_blog_app_v2.blogs index: username_1 dup key: { : null }
this is my schema
var mongoose = require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");
var BlogSchema = new mongoose.Schema({
title: String,
image: String,
body: String,
created: {
type: Date,
default: Date.now
},
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String
}
});
BlogSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("Blog", BlogSchema);
this is the user schema
var mongoose = require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");
var UserSchema = new mongoose.Schema({
username: String,
password: String,
});
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", UserSchema);
this is the create new post route
app.post("/blogs", isLoggedIn, function (req, res) {
req.body.blog.body = req.sanitize(req.body.blog.body);
var title = req.body.blog.title;
var image = req.body.blog.image
var body = req.body.blog.body;
var created = req.body.blog.created;
var author = {
id: req.user._id,
username: req.user.username
}
var newPost = {
title: title,
image: image,
body: body,
created: created,
author: author
}
Blog.create(newPost, function (err, newBlog) {
if (err) {
console.log(err);
res.render("new");
} else {
console.log(newBlog);
res.redirect("/blogs");
}
});
});
I've tried to dropped the entire database using db.dropDatabase() from the mongo console but the problem still persist, not sure what to do now
This is caused by passport-local-mongoose, which, according to its fine manual, makes username a unique field by default.
You have added this plugin to BlogSchema, which seems like you initially had the user data in that schema but moved it to a separate schema (UserSchema) and forgot to remove it from the former.
Start by not using it for BlogSchema, and you also need to drop the unique index on username on the blogs collection.
Can you try deleting your Schema and again send the value? I was getting the same issues. I solved with the above idea.

Nodejs, Mongoose and Jade get no data from Database

i was searching for my Problem but even don't know where is the problem.
I get the title which is set in my route but no data from the database...
My model:
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
ObjectId = Schema.Types.ObjectId;
var blogSchema = new Schema({
title: { type: String, required: true },
author: { type: String, required: true },
body: { type: String, required: true },
date: { type: String, required: true },
hidden: Boolean
});
module.exports = mongoose.model('Blog', blogSchema);
my router:
var express = require('express'),
Blog = require('../models/blog'),
moment = require('moment');
moment.lang('de');
var router = express.Router();
router.get('/articles', function(req, res) {
Blog.find(function(err, docs){
return res.render('blog/articles', {
title: 'Blog_',
articles: docs
});
});
});
app.use('/blog', router);
my jade
extends ../layouts/default
include ../elements/form-elements
block content
h1= title
each article in articles
.col-md-12
div.title= article.title
the only one i get displayed at the Page is
Blog_
So what iam doing wrong?
At the error file it only says:"Cannot read property 'title' of undefined"
So the articles objects are not set...but why?
Thanks so much
edit 1:
change article.title to article doesn't change anything
in the log files is
GET /blog/articles HTTP/1.1 304 - - 3 ms
edit 2:
it seems that node doesnt get any data from the db...
and yes there is one testdata set ;)
console.log() ->
err: null
docs: []
Solution is posted as answer
got the solution...
the model wasn't right...
var blogSchema = new Schema({
title: { type: String, required: true },
author: { type: String, required: true },
body: { type: String, required: true },
date: { type: String, required: true },
hidden: Boolean
}, {collection : 'blog'});
have to name the collection at the end...cause its written in small letters -.-
What a false - never ever do it again ^^
I know this is a very old question and it's marked by OP as answered, but I think the real problem was in "my router", you're not referencing your "docs" (the data coming back from the database) correctly. Keep in mind "docs" is an array so you would need to reference them like this:
router.get('/articles', function(req, res) {
Blog.find(function(err, docs){
return res.render('blog/articles', {
title: docs[0].title, // Get the title for first entry
articles: docs[0].body // Get body for the first entry
});
});
});
I'm hardcoding the array index but you can use a loop to get every item from the array.
I don't think OPs solution fixes the problem because...
By default, when compiling models with:
const someModel = mongoose.model('someModel', SomeSchema);
mongoose creates a collection using 'someModel' name and adding an "s" at the end, so if you check your database, your collection should
appear as 'someModels'. With OP's solution:
{ collection: 'blog' }
as the second parameter when creating the blog schema
var blogSchema = new Schema();
That default behavior is overwritten and the name of your collection will be whatever you set as the value for collection, in this case, "blog".
You can read more about it in Mongoose official docs
or in the Models section in MDN - Node/Express/Mongoose

Resources