Node js aggregation and findone concept - javascript

I need to find the history of person1 deals..so in my getHistory module i have filtered all the deals in that person1's dealSchema , in acceptreject function i have used aggregation concept to filter the deals which have person1's _d in the accepted field. But the callback function acceptreject does not fetch the result it always results in []..anyone please findout the mistake i have done in this code..Thanks in advance
var acceptreject = function (userId, callback){//callback function for finding accepted deal
console.log("Aggregate:" +userId);
if(userId == null && userId == 'undefined'){
console.log("error fetching id");
res.send(new Response.respondWithData('failed','Invalid userId'));
return next();
}
User.aggregate([
{
$unwind: "$deals"
},
{
"$match":
{
"deals.accepted": userId
//"deals.rejected": id
}
},
{
$project:{
"shopName":"$deals.shopName",
"deal":"$deals.deal",
"price":"$deals.price",
"name":"$name"
}
}
],function (err, user){
console.log(user);
if (err){
callback (err);
}
console.log("Your accepted deal:"+ user);
// res.send(200,user);
callback(null, user);
})
}
exports.getHistory = function (req, res, next) {
var incomingUser = req.user;
var id = incomingUser._id;
User.findById(id,function (err, user){
console.log(user);
if (err) {
return next(new Response.respondWithData('failed','Cant find theuser'));
}
var dealObj = _.filter(user.deals);
acceptreject({
userId : id
},function(err, users){
if(err){
res.send(new restify.InternaError(err.message));
return next();
}
else{
console.log("final");
var final = {
accepteddeal: users,//it returns [] in result but person1 accepted the deal
mydeal: dealObj
}
next(res.send(200, final));
}
});
});
}
And my schema is
var dealSchema = new mongoose.Schema({
shopName: {type: String,required: true},
deal: {type: String,required: true},
price:{type: Number,required: true},
start:{type: Date,default: Date.now},
end:{type: Date},
expiry:{type: Date},
comments:{type: String},
accepted: {type:mongoose.Schema.Types.ObjectId, ref:'user'},//person1 _id
rejected: {type:mongoose.Schema.Types.ObjectId, ref: 'user'}
});
var userSchema = new mongoose.Schema({
name: { type: String,required: true},
phone: { type: Number, required: true,unique: true},
email:{type: String},
password: {type: String},
deals:[dealSchema]
}, {collection: 'user'});
mongoose.model('Deal', dealSchema);
mongoose.model('user', userSchema);

I have done a mistake in callback function where the userId parameter of that function does not pass the id
var accept= function (userId, callback){
console.log("Aggregate:" +userId);
if(userId == null && userId == 'undefined'){
res.send(new Response.respondWithData('failed','Invalid userId'));
return next();
}
var id = new Object(userId);
console.log(id);
User.aggregate([
{
$unwind: "$deals"
},
{
"$match": {
"deals.accepted" : id
}
},
{
$project:{
"shopName":"$deals.shopName",
"deal":"$deals.deal",
"price":"$deals.price",
"name":"$name"
}
}
],function (err, user){
console.log(user);
if (err){
callback(err);
}
console.log("Your accepted deal:"+ user);
//res.send(200,user);
callback(null, user);
})
}

Related

How to filter data from mongo collection subarray with subarray data of other collection

Baiscally making a node.js, mongodb add friends functionality where having the option of list user to add in friends list, sent friends request, accept friends request, delete friends request, block friends request.
Register Collection
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let Register = new Schema(
First_Name:{
type: String,
required: true
},
Last_Name: {
type: String
},
Email: {
type: String,
unique: true,
lowercase: true,
required: true
},
Friends:[{type: String}],
});
module.exports = mongoose.model('Register', Register);
Friends Collection
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
var ObjectId = require('mongodb').ObjectID;
let Friends = new Schema({
Requester: {
type: ObjectId,
required: true
},
Recipients: [{Recipient:{type:ObjectId},Status:{type:Number}}],
});
module.exports = mongoose.model('Friends', Friends);
Inside Node.js Post API
var Register = require('../models/register.model');
var Friends =require('../models/friends.model');
router.post('/getdata',function(req,res)
{
let Email="example#example.com";
Register.findOne({ Email : Emails }, function(err, user) {
Friends.findOne({ Requester :user._id }, function(err, user1) {
Register.find({$and:[{Friends:{$nin:[user._id]}},{_id:{$ne:user1.Recipients.Recipient}}]},function(err, user2) {
console.log("user2",user2);
//Here User2 data is not coming
//How to get data so can able to list user that is not added yet in FriendList
//Mainly user1.Recipients.Recipient this is not working because //Recipients is array so how can match all data with array, if i am //using loop then find return data scope ends on inside find closing //braces only.
//Any suggestion
});
});
});
So if I have it correct, you want to do the following:
Find a registration based on a given email
Find the friends related to this user
Find registrations that are not yet in the friend list of the user
Also, given what you've typed, I'm assuming A can be the friend of B, but that doesn't mean B is the friend of A.
While the data structure you currently have may not be optimal for this, I'll show you the proper queries for this:
var Register = require('../models/register.model');
var Friends =require('../models/friends.model');
router.post('/getdata',function(req,res) {
const email = "example#example.com";
Register.findOne({ Email: email }, function(err, user) {
if (err) {
console.error(err);
return;
}
Friends.findOne({ Requester: user._id }, function(err, friend) {
if (err) {
console.error(err);
return;
}
const reciptientIds = friend.Recipients.map(function (recipient) {
return recipient.Recipient.toString();
});
Register.find({Friends: { $ne: user._id }, {_id: { $nin: recipientIds }}, function(err, notFriendedUsers) {
if (err) {
console.error(err);
return;
}
console.log(notFriendedUsers);
});
});
});
});
P.S. This "callback hell" can be easily reduced using promises or await/defer
Finally able to solve it, below is the solution
var Register = require('../models/register.model');
var Friends =require('../models/friends.model');
router.post('/getdata',function(req,res)
{
let Emails="example#example.com";
Register.findOne({$and:[{ Email : Emails}] }, function(err, user) {
if (err) {
console.error(err);
return;
}
Friends
.findOne({ Requester: user._id },
{ _id: 0} )
.sort({ Recipients: 1 })
.select( 'Recipients' )
.exec(function(err, docs){
docs = docs.Recipients.map(function(doc) {
return doc.Recipient; });
if(err){
res.json(err)
} else {
console.log(docs,"docs");
Register.find({$and:[{Friends: { $ne: user._id }},{_id: { $nin: docs }},{_id:{$ne:user._id}}]}, function(err, notFriendedUsers) {
if (err) {
console.error(err);
return;
}
console.log(notFriendedUsers);
});
}
})
});

mongodb Error mongoose do not push object in array $pushAll

I have a simple app with User and Post models,
var mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/assoc", {useMongoClient:true});
mongoose.Promise = global.Promise;
//Post
var postSchema = new mongoose.Schema({
title: String,
content: String
});
var Post = mongoose.model("Post", postSchema);
//User
var userSchema = new mongoose.Schema({
email: String,
name: String,
posts: [postSchema]
});
var User = mongoose.model("User", userSchema);
I Create a user before (name: "gino") and push a post into:
// var newUser = new User({
// email: "a.b#c.it",
// name: "gino"
// });
//
// newUser.posts.push({
// title: "gino's post",
// content: "this is content"
// });
//
// newUser.save(function (err, user) {
// if (err) {
// console.log(err);
// } else {
// console.log(user);
// }
// });
Also create another post to check if Post model works:
// var newPost = new Post({
// title: "honky",
// content: "tonky"
// });
//
// newPost.save(function (err, post) {
// if (err) {
// console.log(err);
// } else {
// console.log(post);
// }
// });
When I try to find "gino" and push a new item into the posts array I have an error trying to save user (user.save) with this snippet:
User.findOne({name: "gino"}, function (err, user) {
if (err) {
console.log(err);
} else {
console.log(user);
user.posts.push({
title: "post",
content: "content"
});
user.save(function (err, user) {
if (err) {
console.log(err);
} else {
console.log(user);
}
});
}
});
When I run the app i got this:
{ MongoError: Unknown modifier: $pushAll
at Function.MongoError.create (appFolder\node_modules\mongodb-core\lib\error.js:31:11)
at toError (appFolder\node_modules\mongodb\lib\utils.js:139:22)
at appFolder\node_modules\mongodb\lib\collection.js:1059:67
at appFolder\node_modules\mongodb-core\lib\connection\pool.js:469:18
at _combinedTickCallback (internal/process/next_tick.js:131:7)
at process._tickCallback (internal/process/next_tick.js:180:9)
name: 'MongoError',
message: 'Unknown modifier: $pushAll',
driver: true,
index: 0,
code: 9,
errmsg: 'Unknown modifier: $pushAll' }
Someone can help me?
Try using findOneAndUpdate instead.
User.findOneAndUpdate(
{ name: "gino" },
{ $push: { posts: { title: 'post', content: 'content' } } },
{ new: true },
function (err, user) {
if(err) console.log("Something wrong when updating data");
console.log(user);
});
Hope it helps!
If you are using 3.5 MongoDB version or higher, can be an issue with $pushAll, which is deprecated.
I founded an option to work around setting usePushEach to true:
new Schema({ arr: [String] }, { usePushEach: true });
Founded in:
https://github.com/Automattic/mongoose/issues/5574#issuecomment-332290518
Can be useful to use the with .push.

Mongoose find not executing

Here's what I've got in a file called Zone.js,
var mongoose = require('mongoose');
mongoose.set('debug', true);
var zoneSchema = new mongoose.Schema({
name: {type: String, required: true, default: '', required: true},
timestamp: {type: Date, default: Date.now, required: true},
zipCodes: {type: [String], default: [], required: true}
});
module.exports = mongoose.model('Zone', zoneSchema);
And then here's what I've got in a file called zoneController.js,
var Zone = require('../models/Zone');
module.exports = {
find: function(params, callback){
console.log('Finding zone');
Zone.find(params, function(err, zones){
console.log('Got results');
if (err){
callback(err, null);
return;
}
callback(null, zones);
});
}
}
And then, I have,
ZoneController = require('../controllers/zoneController');
ZoneController.find({}, function(err, results){
console.log('Zone results received');
}
The problem is that the .find() method doesn't give me anything. I get 'Finding zone' in my console, but absolutely nothing after that.
My folder structure is correct and I am referencing the correct files.
try this, I think that you must to return your find method in your controller.
let me know if it work.
module.exports = {
return {
find: function(params, callback) {
console.log('Finding zone');
Zone.find(params, function(err, zones) {
console.log('Got results');
if (err) {
callback(err, null);
return;
}
callback(null, zones);
});
}
}
}
Here is a .find example for Tweet model in one of my old projects.
Tweet.find({}).sort({date: -1}).populate('_creator').exec((err, tweets) => {
res.render('tweet-all', {title: `All Tweets`, tweets: tweets});
});
I think you must use .exec() in Model.

MongoDB references with Node.js I can not populate

I want to show user's location information on the screen.
For Example:
name: "Andy" surname : "Carol" City : "Istanbul" Town : "Kadıkoy"
When I call the getuser function I want to display the City and Town name.
This is my code:
UserSCHEMA
// Model for the User
module.exports = (function userSchema() {
var Mongoose = require('mongoose');
var Schema = Mongoose.Schema;
var userSchema = new Schema({
name: {
type: String,
require: true
},
surname: {
type: String,
require: true
},
tel: {
type: String,
require: true
},
age: {
type: String,
require: true
},
mevki_id: {
type: String,
require: true
},
lok_id: [{
type: Mongoose.Schema.Types.ObjectId,
ref: 'locations'
}]
});
var collectionName = 'users';
var USERSCHEMA = Mongoose.Schema(userSchema);
var User = Mongoose.model(collectionName, USERSCHEMA);
return User;
})();
USERController
//This Controller deals with all functionalities of User
function userController() {
var User = require('../models/UserSchema');
// Creating New User
this.createUser = function (req, res, next) {
var name = req.body.name;
var surname = req.body.surname;
var tel = req.body.tel;
var age = req.body.age;
var mevki_id = req.body.mevki_id;
var lok_id = req.body.lok_id;
User.create({
name: name,
surname: surname,
tel: tel,
age: age,
mevki_id: mevki_id,
lok_id: lok_id
}, function (err, result) {
if (err) {
console.log(err);
return res.send({
'error': err
});
} else {
return res.send({
'result': result,
'status': 'successfully saved'
});
}
});
};
//Populateeee
this.getUser = function (req, res, next) {
User.find().populate('lok_id')
.exec(function (err, result) {
if (err) {
console.log(err);
return res.send({
'error': err
});
} else {
return res.send({
'USERS': result
});
}
});
};
return this;
};
module.exports = new UserController();
Location Schema
//Schema for Location
module.exports = (function LocationSchema() {
var Mongoose = require('mongoose');
var Schema = Mongoose.Schema;
var LocationSchema = new Schema({
userid: {
type: Mongoose.Schema.Types.ObjectId,
ref: 'users'
},
il: {
type: String,
require: true
},
ilce: {
type: String,
require: true
}
});
var collectionName = 'locations';
var LocationSCHEMA = Mongoose.Schema(schema);
var Location = Mongoose.model(collectionName, LocationSCHEMA);
return Location;
})();
Location Controller
//This Controller deals with all functionalities of Location
function locationController() {
var location = require('../models/LocationSchema');
// Creating New Location
this.createLocation = function (req, res, next) {
var userid = req.params.userid;
var il = req.params.il;
var ilce = req.params.ilce;
location.create({
userid: userid,
il: il,
ilce: ilce
}, function (err, result) {
if (err) {
console.log(err);
return res.send({
'error': err
});
} else {
return res.send({
'result': result,
'status': 'successfully saved'
});
}
});
};
// Fetching Details of Location
this.getLocation = function (req, res, next) {
location.find({}, function (err, result) {
if (err) {
console.log(err);
return res.send({
'error': err
});
} else {
console.log(result);
return res.send({
'location Details': result
});
}
});
};
return this;
};
module.exports = new locationController();
I already had a problem with model definition.
It was fixed by adding the third parameter to mongoose.model (the explicit collection name)
// Try to replace :
var collectionName = 'users';
var USERSCHEMA=Mongoose.Schema(userSchema);
var User = Mongoose.model(collectionName, USERSCHEMA);
// with:
var collectionName = 'users';
var USERSCHEMA=Mongoose.Schema(userSchema);
var User = Mongoose.model(collectionName, USERSCHEMA, collectionName);
the collectionName must be set either in the schema definition or in the model definition. for more details see here

mongoose query .where/.and after .populate

I need to test if a user has the given id, a project with a specified id and a role with a given name.
var UserSchema = new Schema({
roles: [{
project: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Project',
},
role: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Role',
}
}]
});
and
var RoleSchema = new Schema({
name: {
type: String
}
});
I tryed to .populate and then apply .where, but .where does nothing.
Using an .and after populate does not work either.
How to solve this in mongodb/mongoose?
Thank you!
//EDIT
Right now I have something like that, which does not work (.where does nothing) and it is really not beautiful:
User.findById(userId)
.populate({
path: 'roles.role',
match: { 'name': roleName}
})
.where('roles.project').equals(projectId)
.exec(function(err, data){
data.roles = data.roles.filter(function(f){
return f.role;
})
if(!err){
if(data){
if(data.roles.length == 1) {
return true;
}
}
}
return false;
});
When I do what Kevin B said:
Role.findOne({name: roleName}, function(err, data){
if(!err){
if(data){
User.findById(userId)
.and([
{'roles.project': projectId},
{'roles.role': data._id}
])
.exec(function(err2, data2){
if(!err2){
if(data2){
console.log(data2);
}
}
});
}
}
});
The .and query just does nothing here...
Now I'm just doing comparisons in the program instead of the database.
User.findById(userId)
.populate('roles.role')
.exec(function(err, data){
if(!err){
if(data){
if(data.roles.find(function(element, index, array){
return element.project == projectId && element.role.name == roleName;
}))
return callback(true);
}
}
return callback(false);
});

Categories

Resources