fetch all the users with specific attribute - node.js

Hey everybody Im new with node and mongo hope for your help with it.
I defined a user schema with mongoose:
var userSchema = mongoose.Schema({
local : {
email : String,
password : String,
name : String
},
facebook : {
id : String,
email : String,
token : String,
firstName : String,
familyName : String
},
google : {
id : String,
email : String,
token : String,
firstName : String,
familyName : String
}});
Im tring to fetch all the users (from local google and facebook) with specific email.
How do I write it ?
I tried something like:
var User = require('./models/user');
app.get('/api/user/:email',function(req,res){
User.findOne({'email':req.params.email},function(err,user){
res.json(user);
})
});
How do I fix it ?
Thanks.

Add
module.exports = mongoose.model("User", userSchema);
to your schema file.
Then try the following:
var User = require('./models/user');
app.get('/api/user/:email',function(req,res){
User.findOne({"local.email": req.params.email}, function(err,user){
res.json(user);
});
});
Or for all three:
var User = require('./models/user');
app.get('/api/user/:email',function(req,res){
User.findOne({$or: [
{"local.email": req.params.email},
{"facebook.email": req.params.email},
{"google.email": req.params.email}
]}, function(err,user){
res.json(user);
});
});

Related

Why won't my rest api post request save my array in my mongodb database

I'm trying to learn to make an api with node.js For my backend i'm using mongodb and I'm using mongoose as ORM. I created my user model as follows.
// User.js
var mongoose = require('mongoose');
var UserInfoSchema = new mongoose.Schema({
street: String,
housenumber: String,
city: String,
postcode: String,
bus: String,
});
var UserFullSchema = new mongoose.Schema({
name: String,
email: String,
password: String,
Userinfo: [UserInfoSchema]
});
mongoose.model('User', UserFullSchema);
const User = mongoose.model('user',UserFullSchema)
module.exports = User;
My Usercontroller looks like this:
// UserController.js
var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
router.use(bodyParser.urlencoded({ extended: true }));
var User = require('./User');
// CREATES A NEW USER
router.post('/', function (req, res) {
User.create({
name : req.body.name,
email : req.body.email,
password : req.body.password,
Userinfo: [{
street : req.body.street,
housenumber : req.housenumber,
city : req.body.city,
postcode : req.body.postcode,
bus : req.body.bus,
}]
},
function (err, user) {
if (err) return res.status(500).send("There was a problem adding the information to the database.");
res.status(200).send(user);
});
});
For some reason when I call my API using postman to test I can never seen to be able populate my array. Did I do something wrong?
Picture as example:
Page I checked before posting:
Page I checked
You definition where you want to have a cross reference by the _id seems off.
Userinfo: [UserInfoSchema]
should probably be:
Userinfo: [{ type: mongoose.Schema.Types.ObjectId, ref: 'UserInfoSchema' }]
This way you would have a cross reference by _id. Btw not a fan of those names. It reads very confusing. I assume these are just for testing.
Now, from a simple express kinda perspective Are you even referencing the values from req.body?
Shouldn't the values be req.body.Userinfo.street?
Userinfo: [{
street : req.body.Userinfo.street, //
housenumber : req.body.Userinfo.housenumber,
city : req.body.Userinfo.city,
postcode : req.body.Userinfo.postcode,
bus : req.body.Userinfo.bus,
}]
On a side note, you can send Full fledged JSON using postman, go to the raw tab and select application/json from the dropdown
I dont know what the problem was but I was able to resolve the issue by splitting my models in 2 different files.
I made a new file called Userinfo like this:
// Userinfo.js
var mongoose = require('mongoose');
var UserInfoSchema = new mongoose.Schema({
street: String,
housenumber: String,
city: String,
postcode: String,
bus: String,
});
module.exports = UserInfoSchema;
There I exported my whole Schema
And called that Schema in my User model file like this:
// User.js
var Userinfo = require('../userinfo/Userinfo.js');
var mongoose = require('mongoose');
var UserFullSchema = new mongoose.Schema({
name: String,
email: String,
password: String,
Userinfo: [Userinfo]
});
const User = mongoose.model('user',UserFullSchema)
module.exports = User;
And my controller looked like this:
// UserController.js
var express = require('express');
var mongoose = require('mongoose');
var router = express.Router();
var bodyParser = require('body-parser');
router.use(bodyParser.urlencoded({ extended: true }));
var User = require('./User');
router.post('/', function (req, res) {
User.create({
name : req.body.name,
email : req.body.email,
password : req.body.password,
Userinfo: [{
street : req.body.Userinfo.street,
housenumber : req.body.Userinfo.housenumber,
city : req.body.Userinfo.city,
postcode : req.body.Userinfo.postcode,
bus : req.body.Userinfo.bus,
}]
},
function (err, user) {
if (err) return res.status(500).send("There was a problem adding the information to the database.");
res.status(200).send(user);
console.log(req);
});
});
After that I used postman as before and voila issue resolved:

how to find the document in mongodb database which contain multiple collections in a schema

Below is my MongoDB schema.
var userSchema = mongoose.Schema({
local : {
username :String,
name : String,
email : String,
password : String,
},
facebook : {
id : String,
token : String,
email : String,
name : String
},
twitter : {
id : String,
token : String,
displayName : String,
username : String
},
google : {
id : String,
token : String,
email : String,
name : String
}
});
I want to find the document which contains username which I specify in the argument and to achieve it I write below line of code
module.exports.getUserByUsername = function(username, callback){
var u = new User();
var query = {u.local.username: username};
User.findOne(query, callback);
}
but it says unexpected token.What should I have to do?
Your query needs to provide the name of the field to match against using a dot-notation string:
var query = {'local.username': username};

Mongoose returns empty while the same query in mongodb shell works fine

I know maybe this question has been asked quite many times here, I've went through several solutions people came with to similar questions but none of them seemed to help in my case.
I have two collections called users and posts and models for them look like this:
users
var mongoose = require('mongoose').set('debug', true);
var Schema = mongoose.Schema;
var usersSchema = new Schema({
name: {type: String, required: true}
});
var User = mongoose.model('user', usersSchema, 'users');
module.exports = User;
posts
var mongoose = require('mongoose').set('debug', true);
var Schema = mongoose.Schema;
var postsSchema = new Schema({
content: String,
user: {
type: Schema.ObjectId,
ref: 'users',
required: true
}
});
var Post = mongoose.model('post', postsSchema, 'posts');
module.exports = Post;
I'm trying to get the posts of a user using this code:
var Post = require('../models/posts');
...
router.get('/posts/user/:userId', function (req, res, next) {
Post.find({user: req.params.userId}, function (err, posts) {
Post.populate(posts, {path: 'user'}, function(err, posts) {
res.send(posts);
});
});
});
Mongoose debug mode reports that the following query is executed during the request:
posts.find({ user: ObjectId("592e65765ba8a1f70c1eb0bd") }, { fields: {} })
which works perfectly fine in mongodb shell (I'm using Mongoclient) but with Mongoose this query returns an empty array.
The query I run in mongodb shell:
db.posts.find({ user: "592e65765ba8a1f70c1eb0bd" })
The results I get:
{ "_id" : ObjectId("592e66b48f60c03c1ee06445"), "content" : "Test post 3", "user" : "592e65765ba8a1f70c1eb0bd" }
{ "_id" : ObjectId("592e66b98f60c03c1ee06446"), "content" : "Test post 4", "user" : "592e65765ba8a1f70c1eb0bd" }
{ "_id" : ObjectId("592e66bb8f60c03c1ee06447"), "content" : "Test post 5", "user" : "592e65765ba8a1f70c1eb0bd" }
I'm at the very beginning on learning Node.JS and MongoDB, so maybe I've missed something.
Thank you in advance!
As Neil Lunn suggested, I checked the user field type and it was indeed of type String instead of ObjectId so there was a mismatch of types between the data stored in collection and the field type from the query.
I used this code to convert the user field type from String to ObjectId in my collection:
db.getCollection('posts').find().forEach(function (post) {
db.getCollection('posts').remove({ _id : post._id});
tempUserId = new ObjectId(post.user);
post.user = tempUserId;
db.getCollection('posts').save(post);
}
);
Now everything works as expected.

Empty objects using app.post and AngularJS + mongoose on node.js

My REST API is posting empty objects.
I am getting the value from req.body.name
If I log it console.log(req.body.name); I get the value on my console.
POST:
{ name: 'typing any name', status: null }
typing any name
So the workflow between my frontend (angular.js), the form and the backend (node.js, express, mongoose) seems to work. Now I POST the value, but I get an empty object in my mongoDB.
{"_id":"543a50a974de6e2606bd8478","__v":0}
app.post('/api/offers', function (req, res){
var offer;
console.log("POST: ");
console.log(req.body);
console.log(req.body.name);
offer = new OfferModel({
name: req.body.name,
value: req.body.value,
title: req.body.title,
content: req.body.content,
});
offer.save(function (err) {
if (!err) {
return console.log("created offer" + req.body.name);
} else {
return console.log(err);
}
});
return res.send(offer);
});
And here is the model:
var offerSchema = mongoose.Schema({
offer : {
name : String,
value : String,
title : String,
content : String,
image : String,
start : String,
end : String,
targets : String,
beacons : String,
published : String
}
});
var OfferModel = mongoose.model('Offer', offerSchema);
Schema is incorrect, must be like this:
var offerSchema = mongoose.Schema({
name : String,
value : String,
title : String,
content : String,
image : String,
start : String,
end : String,
targets : String,
beacons : String,
published : String
});

Node.js - How to create a unique id with mongoose db

I am working with Twitter authentication and want to store the twitter id as unique key in mongodb. However i see multiple entries with the same id. Here's my schema and code
Schema:
var TwitterSchema = new Schema({
accessToken: String,
accessTokenSecret: String,
name: String,
twitterId: { type: String, required: true, index: { unique: true, sparse: true } }
});
Code:
mongoose.connect('mongodb://localhost/twd')
mongoose.model('Post', TwitterSchema);
var Post = mongoose.model('Post');
var post = new Post();
post.accessToken = accessToken
post.accessTokenSecret = accessTokenSecret
post.name = twitterUserData.name
post.twitterId = twitterUserData.id
post.save(function(err){
if (err){
throw err;
promise.fail(err);
}
console.log('saved');
mongoose.disconnect();
});
promise.fulfill(post);
DB shell output
> db.posts.find();
{ "twitterId" : "21475255", "name" : "MMMK", "accessTokenSecret" : "ZYhiXMWfXvSr1aaCB93hgU243j8aapP0ALdSFlWEE", "accessToken" : "22475255-9YvKMceUInUIxcEtKAK0oMRRG2ZZxn5c52vnwPw", "_id" : ObjectId("4feddf6155203990e000001") }
{ "twitterId" : "21475255", "name" : "MMMK, "accessTokenSecret" : "ZYhiXMWfXvSr1aaCB93hgU2438aapP0ALdSFlWEE", "accessToken" : "22475255-9YvKMceUInUIxcEtKAK0oMRRG2ZZxn5c52vnwPw", "_id" : ObjectId("4feddf7b5905a1a10e000001") }
My guess is either the index isn't being created in MongoDB, or the index with the same name already exits. If it already exists, mongoose will use ensureIndex to create it, but that won't override/redefine it if it already exists. Use the mongo js shell to see if it exists, then try dropping it, restarting mongod, and running your node.js code again.
http://www.mongodb.org/display/DOCS/Indexes#Indexes-CreationOptions

Resources