How to get conversation list between two user in MongooseJs - node.js

i'm new to MongoDB and trying to build a simple chat app using Node.Js and MongoDB using mongoose Js. and i'm stuck here for last 2 days so need help!!
Tested most of the related answer of stack overflow but not getting desirable result.
What i want to achieve is something similar we see in chat application like Facebook Messenger and whatsApp web where in one side we see all our conversation list which show last message and person profile.
an example here http://roba.laborasyon.com/demos/dark/ (left sidebar)
this is how my model look like
const chat = new Schema({
to:{
type:Schema.Types.ObjectId,
ref:"User",
required:true,
},
from:{
type:Schema.Types.ObjectId,
ref:"User",
required:true,
},
seenbySender:Boolean,
seenByReceiver:Boolean,
isFile:{
type:Boolean,
default:false
},
file:{
type:Object,
required:false,
},
text:String,
},{timestamps:true});
In My Controller or route file (this is not my code but i tried similar logic they all return empty array or error)
exports.test = (request,response,next) => {
let {user} = request.body;
const u=await User.findById(user);
//Chat.find({from:user}).populate('from').populate('to').then(r => response.json(r));
//user ="5f46319ac483a43d98ae3626";
Chat.aggregate([
{$match:{$or:[{"to":user},{"from":user}]}},
{
$group:{"_id":
{
"text":{
$cond:[
{
$gt:[
{$substr:["$to",0,1]},
{$substr:["$from",0,1]}]
},
{$concat:["$to"," and ","$from"]},
{$concat:["$from"," and ","$to"]}
]
}
},
"text":{$first:"$text"}
}
}]).then(result => {
response.json(result)
}).catch(error => {
console.log("[[error]]",error)
response.json({error})
});
}
Here is data i'm working with (exported JSON file)
[
{
"_id": {
"$oid": "5f4a3ae0a7ff491f3024668e"
},
"isFile": false,
"to": {
"$oid": "5f46325ec483a43d98ae3627"
},
"from": {
"$oid": "5f46319ac483a43d98ae3626"
},
"text": "Hi John,Yash here!",
"createdAt": {
"$date": "2020-08-29T11:24:16.416Z"
},
"updatedAt": {
"$date": "2020-08-29T11:24:16.416Z"
},
"__v": 0
},
{
"_id": {
"$oid": "5f4a3affa7ff491f3024668f"
},
"isFile": false,
"to": {
"$oid": "5f46319ac483a43d98ae3626"
},
"from": {
"$oid": "5f46325ec483a43d98ae3627"
},
"text": "hello Yash - John",
"createdAt": {
"$date": "2020-08-29T11:24:47.519Z"
},
"updatedAt": {
"$date": "2020-08-29T11:24:47.519Z"
},
"__v": 0
},
{
"_id": {
"$oid": "5f4a3b25a7ff491f30246690"
},
"isFile": false,
"to": {
"$oid": "5f4632c8c483a43d98ae3628"
},
"from": {
"$oid": "5f46319ac483a43d98ae3626"
},
"text": "Hello Don, Yash this side.",
"createdAt": {
"$date": "2020-08-29T11:25:25.067Z"
},
"updatedAt": {
"$date": "2020-08-29T11:25:25.067Z"
},
"__v": 0
}
]
So what i need is last message of user he chatted with, with the user reference. in this case for Id: 5f46319ac483a43d98ae3626 the last 2 objects should be render
Thanks a lot!!

You can try using $split to get limited records,
db.collection.aggregate([
{
$match: {
$or: [
{ "to": ObjectId("5f46319ac483a43d98ae3626") },
{ "from": ObjectId("5f46319ac483a43d98ae3626") }
]
}
},
// for descending order
{ $sort: { updatedAt: -1 } },
{
$group: {
_id: {
$cond: [
{ $eq: ["$to", ObjectId("5f46319ac483a43d98ae3626")] },
{ $concat: [{ $toString: "$to" }, " and ", { $toString: "$from" }] },
{ $concat: [{ $toString: "$from" }, " and ", { $toString: "$to" }] }
]
},
updatedAt: { $first: "$updatedAt" },
// push messages
messages: { $push: "$$ROOT" }
}
},
// order by descending order
{ $sort: { updatedAt: -1 } },
// limit to 2 messages only
{ $addFields: { messages: { $slice: ["$messages", 2] } } }
])
Playground
for joining user data you can use $lookup

I guess you can use this schema for a chat
MessageSchema = new mongoose.Schema({
from: {
type: string,
required: true,
},
to: {
type: string,
required: true,
},
time: {
type: Date,
default: Date.now(),
},
message: {
type: string,
required: true,
},
});
ChatSchema = new mongoose.Schema({
firstUserId:{
type: mongoose.Schema.Types.ObjectId,
required: true,
},
secondUserId:{
type: mongoose.Schema.Types.ObjectId,
required: true,
},
Chat: MessageSchema,
})
and data will be as this way
[
{
firstUserId: "hjakdsf323275lks",
secondUserId: "asdfe2342232aas",
Chat: [
{
from: "hjakdsf323275lks",
to: "asdfe2342232aas",
time: "18/7/2020 20:06:09",
message: "Hi ",
},
{
from: "asdfe2342232aas",
to: "hjakdsf323275lks",
time: "18/7/2020 21:07:09",
message: "hello ",
},....
],
},
];

Related

Querying nested objects using find not working in mongoose (MongoDB)

I'm trying to get an object which has isDraft value true, but I'm also getting objects which have isDraft value false. I need only objects having isDraft value true. I have tried all possible ways but am not able to find a solution for this. Can anyone help me with this?
Below are the schema, query and response.
Schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Contract = new Schema({
name: {
type: String,
unqiue: true,
required: true
},
version: [
{
no: {
type: Number,
required: true
},
sections: [
{
sectionName: {
type: String,
required: true
},
clause: [{
description: {
type: String,
required: true
},
}]
}
],
approvedBy: [
{
user: {
type: Schema.Types.ObjectId,
ref: 'user'
},
}
],
acceptedBy: [
{
name: {
type: String,
},
eamil: {
type: String,
},
}
],
isDraft: {
type: Boolean,
required: true
},
date: {
type: Date,
default: Date.now
}
}
],
createdBy: {
type: Schema.Types.ObjectId,
ref: 'user',
required: true
},
});
module.exports = mongoose.model('contract', Contract);
Query
query = {
$and: [
{ createdBy: clientAdminDetails._id },
{ "version.isDraft": true }
],
};
await Contract
.find(query)
.skip(req.body.noOfItems * (req.body.pageNumber - 1))
.limit(req.body.noOfItems)
.exec((err, contract) => {
if (err) {
return res.json(err);
}
Contract.countDocuments(query).exec((count_error, count) => {
if (err) {
return res.json(count_error);
}
return res.json({
total: count,
page: req.body.pageNumber,
pageSize: contract.length,
contracts: contract
});
});
});
Response
{
"total": 1,
"page": 1,
"pageSize": 1,
"contracts": [
{
"_id": "61449469775..",
"name": "Octavia Blankenship",
"version": [
{
"_id": "614496593cc..",
"sections": [
{
"_id": "61449469775..",
"sectionName": "Est dolore dolorem n Updated `1323",
"clause": [
{
"_id": "614494697..",
"description": "Numquam nostrud et a"
}
]
}
],
"isDraft": false,
"no": 1,
"approvedBy": [],
"acceptedBy": [],
"date": "2021-09-17T13:21:29.509Z"
},
{
"_id": "614496122904ee4e046fbee8",
"sections": [
{
"_id": "6144955a8c0061025499606f",
"sectionName": "Praesentium suscipit",
"clause": [
{
"_id": "6144955a8c00610254996070",
"description": "Velit aperiam ut vel"
}
]
}
],
"isDraft": true,
"no": 2,
"approvedBy": [],
"acceptedBy": [],
"date": "2021-09-17T13:20:18.128Z"
}
],
"createdBy": "614367e980b29e6c...",
"__v": 0
}
]
}
This is why using your query you are telling mongo "Give me a document where createdBy is desired id and version.isdraft is true" So, as the DOCUMENT contains both values, is returned, even existing false into the array.
To solve this you have many ways.
First one is using $elemMatch into projection (docs here). But using this way only the first element is returned, so I think you prefer other ways.
So you can use an aggregation query using $filter like this:
First $match by values you want (as in your query).
Then override version array filtering by values where isDraft = true.
db.collection.aggregate([
{
"$match": {
"createdBy": "",
"version.isDraft": true
}
},
{
"$set": {
"version": {
"$filter": {
"input": "$version",
"as": "v",
"cond": {
"$eq": [
"$$v.isDraft",
true
]
}
}
}
}
}
])
Example here

Update object with value of array

For a project where we have actions and donations. We store the donations in an array in the related action. For the connection we use Mongoose.
The schema for an action is as follows, for readability I've removed some fields which are not related to this problem:
const donationSchema = new Schema(
{
id: {
type: String,
unique: true,
required: true,
index: true,
},
amount: { type: Number },
status: {
type: String,
enum: ['pending', 'collected', 'failed'],
default: 'pending',
},
},
{ timestamps: true, versionKey: false, _id: false },
);
const schema = new Schema(
{
donations: { type: [donationSchema], default: [] },
target: { type: Number, default: 0 },
collected: { type: Number, default: 0 },
},
{
timestamps: true,
versionKey: false,
},
);
const Action = model<IAction>('Action', schema);
Let say I have an Action with three donations, one in every state:
{
"_id": "6098fb22101f22cfcbd31e3b"
"target": 10000,
"collected": 25,
"donations": [
{
"uuid": "dd90f6f1-56d7-4d8b-a51f-f9e5382d3cd9",
"amount": 25,
"status": "collected"
},
{
"uuid": "eea0ac5e-1e52-4eba-aa1f-c1f4d072a37a",
"amount": 10,
"status": "failed"
},
{
"uuid": "215237bd-bfe6-4d5a-934f-90e3ec9d2aa1",
"amount": 50,
"status": "pending"
}
]
}
Now I want to update the pending donation to collected.
This would be
Action.findOneAndUpdate(
{
_id: '6098fb22101f22cfcbd31e3b',
'donations.id': '215237bd-bfe6-4d5a-934f-90e3ec9d2aa1',
},
{
$set: {
'donations.$.status': 'collected',
},
},
{
upsert: false,
returnOriginal: false,
}
).then((action) => console.log(action);
I want to update the status to collected, but also update the collected so that it is the same as all the donations with status equal to collected. I thought of using the $inc operator, but this keeps saying that donations.$.amount is not a number and therefore not able to increment collected.
Is there a way to do this in the same update call? The reason why I cannot get the object and just count collected amount is that maybe two donation callbacks occur at the same time, so we don't want the to overwrite the previous given amount.
This aggregation can help you I believe:
db.collection.aggregate([
{
"$match": {
_id: "6098fb22101f22cfcbd31e3b"
}
},
{
"$set": {
"donations.status": {
"$reduce": {
"input": "$donations",
"initialValue": {
uuid: "215237bd-bfe6-4d5a-934f-90e3ec9d2aa1"
},
"in": {
$cond: [
{
$eq: [
"$$this.uuid",
"$$value.uuid"
]
},
"collected",
"$$this.status"
]
}
}
}
}
},
{
"$set": {
"collected": {
"$reduce": {
"input": "$donations",
"initialValue": "$collected",
"in": {
$cond: [
{
$eq: [
"$$this.status",
"collected"
]
},
{
$sum: [
"$$value",
"$$this.amount"
]
},
"$$value"
]
}
}
}
}
}
])
Edit: Above aggregation wasn't properly update status field to "collected" dunno why..
But update query below should work. I couldn't test it too. So, please let me know if something goes wrong.
db.collection.update({
"_id": "6098fb22101f22cfcbd31e3b"
},
{
"$set": {
"donations.$[element].status": "collected",
"$inc": {
"donations.$[element].amount": {
"$cond": [
{
"$eq": [
"donations.$[element].status",
"collected"
]
},
"donations.$[element].amount",
"collected"
]
}
}
}
},
{
"arrayFilters": [
{
"element.uuid": "215237bd-bfe6-4d5a-934f-90e3ec9d2aa1"
}
]
})

How to exclude an fields from populated query data? [duplicate]

This question already has answers here:
Mongoose/Mongodb: Exclude fields from populated query data
(4 answers)
Closed 2 years ago.
I just not want to pass user id in discussion array.
Now I getting back from this route like this.
{
"_id": "5f4600ab7ec81f6c20f8608d",
"name": "2",
"category": "2",
"description": "2",
"deadline": "2020-08-10",
"discussion": [
{
"date": "2020-09-03T06:12:15.881Z",
"_id": "5f5089bd265ec85b896f8491",
"user": {
"_id": "5f5089a2265ec85b896f848f",
"userName": "MdJahidHasan01"
},
"text": "3"
},
{
"date": "2020-09-03T06:12:15.881Z",
"_id": "5f5089ae265ec85b896f8490",
"user": {
"_id": "5f5089a2265ec85b896f848f",
"userName": "MdJahidHasan01"
},
"text": "2"
}
]
}
But I want to get like this
{
"_id": "5f4600ab7ec81f6c20f8608d",
"name": "2",
"category": "2",
"description": "2",
"deadline": "2020-08-10",
"discussion": [
{
"date": "2020-09-03T06:12:15.881Z",
"_id": "5f5089bd265ec85b896f8491",
"user": {
"userName": "MdJahidHasan01"
},
"text": "3"
},
{
"date": "2020-09-03T06:12:15.881Z",
"_id": "5f5089ae265ec85b896f8490",
"user": {
"userName": "MdJahidHasan01"
},
"text": "2"
}
]
}
Select does not working here. I just not want to pass user id in discussion array just username.
As I use user id for authorization. So it is not an good idea to send user id.
Project Model
const mongoose = require('mongoose');
const projectSchema = new mongoose.Schema({
name: {
type: String,
require: true
},
category: {
type: String,
require: true
},
description: {
type: String,
require: true
},
deadline: {
type: String,
require: true
},
discussion: [
{
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
date: {
type: Date,
default: Date.now()
},
text: {
type: String,
require: true
}
}
]
});
module.exports = mongoose.model('Project', projectSchema);
Project Details Route
router.get('/:projectId',async (req, res) => {
try {
const project = await Project.findById(req.params.projectId)
.populate('discussion.user', 'userName')
.select('-discussion.user._id')
console.log(project);
await res.status(200).json(project);
} catch (error) {
console.log(error);
return res.status(400).json({ 'error': 'Server Error' });
}
})
Just add this after the .populate:
delete project.discussion._id

MongoDB aggregate lookup match not working the same without lookup

Can you please help? I'm trying to aggregate data over the past 12 months by both ALL publication data specific to a certain publisher and per publication to return a yearly graph data analysis based on the subscription type.
Here's a snapshot of the Subscriber model:
const SubscriberSchema = new Schema({
publication: { type: Schema.Types.ObjectId, ref: "publicationcollection" },
subType: { type: String }, // Print, Digital, Bundle
subStartDate: { type: Date },
subEndDate: { type: Date },
});
Here's some data for the reader (subscriber) collection:
{
_id: ObjectId("5dc14d3fc86c165ed48b6872"),
publication: ObjectId("5d89db9d82273f1d18970deb"),
subStartDate: "2019-11-20T00:00:00.000Z",
subtype: "print"
},
{
_id: ObjectId("5dc14d3fc86c165ed48b6871"),
publication: ObjectId("5d89db9d82273f1d18970deb"),
subStartDate: "2019-11-19T00:00:00.000Z",
subtype: "print"
},
{
_id: ObjectId("5dc14d3fc86c165ed48b6870"),
publication: ObjectId("5d89db9d82273f1d18970deb"),
subStartDate: "2019-11-18T00:00:00.000Z",
subtype: "digital"
},
{
_id: ObjectId("5dc14d3fc86c165ed48b6869"),
publication: ObjectId("5d8b36c3148c1e5aec64662c"),
subStartDate: "2019-11-19T00:00:00.000Z",
subtype: "print"
}
The publication model has plenty of fields but the _id and user fields are the only point of reference in the following queries.
Here's some data for the publication collection:
// Should use
{ "_id": {
"$oid": "5d8b36c3148c1e5aec64662c"
},
"user": {
"$oid": "5d24bbd89f09024590db9dcd"
},
"isDeleted": false
},
// Should use
{ "_id": {
"$oid": "5d89db9d82273f1d18970deb"
},
"user": {
"$oid": "5d24bbd89f09024590db9dcd"
},
"isDeleted": false
},
// Shouldn't use as deleted === true
{ "_id": {
"$oid": "5d89db9d82273f1d18970dec"
},
"user": {
"$oid": "5d24bbd89f09024590db9dcd"
},
"isDeleted": true
},
// Shouldn't use as different user ID
{ "_id": {
"$oid": "5d89db9d82273f1d18970dfc"
},
"user": {
"$oid": "5d24bbd89f09024590db9efd"
},
"isDeleted": true
}
When I do a lookup on a publication ID with the following, I'm getting perfect results:
Subscriber.aggregate([
{
$match: {
$and: [
{ 'publication': mongoose.Types.ObjectId(req.params.id) },
],
"$expr": { "$eq": [{ "$year": "$subStartDate" }, new Date().getFullYear()] }
}
},
{
/* group by year and month of the subscription event */
$group: {
_id: { year: { $year: "$subStartDate" }, month: { $month: "$subStartDate" }, subType: "$subType" },
count: { $sum: 1 }
},
},
{
/* sort descending (latest subscriptions first) */
$sort: {
'_id.year': -1,
'_id.month': -1
}
},
{
$limit: 100,
},
])
However, when I want to receive data from the readercollections (Subscriber Model) for ALL year data, I'm not getting the desired results (if any) from all of the things I'm trying (I'm posting the best attempt result below):
Publication.aggregate([
{
$match:
{
user: mongoose.Types.ObjectId(id),
isDeleted: false
}
},
{
$project: {
_id: 1,
}
},
{
$lookup: {
from: "readercollections",
let: { "id": "$_id" },
pipeline: [
{
$match:
{
$expr: {
$and: [
{ $eq: ["$publication", "$$id"] },
{ "$eq": [{ "$year": "$subStartDate" }, new Date().getFullYear()] }
],
}
}
},
{ $project: { subStartDate: 1, subType: 1 } }
],
as: "founditem"
}
},
// {
// /* group by year and month of the subscription event */
// $group: {
// _id: { year: { $year: "$founditem.subStartDate" }, month: { $month: "$foundtitem.subStartDate" }, subType: "$founditem.subType" },
// count: { $sum: 1 }
// },
// },
// {
// /* sort descending (latest subscriptions first) */
// $sort: {
// '_id.year': -1,
// '_id.month': -1
// }
// },
], function (err, result) {
if (err) {
console.log(err);
} else {
res.json(result);
}
})
Which returns the desired data without the $group (commented out) but I need the $group to work or I'm going to have to map a dynamic array based on month and subtype which is completely inefficient.
When I'm diagnosing, it looks like this $group is the issue but I can't see how to fix as it works in the singular $year/$month group. So I tried the following:
{
/* group by year and month of the subscription event */
$group: {
_id: { year: { $year: "$subStartDate" }, month: { $month: "$subStartDate" }, subType: "$founditem.subType" },
count: { $sum: 1 }
},
},
And it returned the $founditem.subType fine, but any count or attempt to get $year or $month of the $founditem.subStartDate gave a BSON error.
The output from the single publication ID lookup in the reader collection call that works (and is plugging into the line graph perfectly) is:
[
{
"_id": {
"year": 2019,
"month": 11,
"subType": "digital"
},
"count": 1
},
{
"_id": {
"year": 2019,
"month": 11,
"subType": "print"
},
"count": 3
}
]
This is the output I'd like for ALL publications rather than just a single lookup of a publication ID within the reader collection.
Thank you for any assistance and please let me know if you need more details!!

I am trying to search with populate in express mongoose model, querying after populate in Mongoose ,look what exactly i want

I'm pretty new to Mongoose and MongoDB in general so I'm having a difficult time figuring out if something like this is possible:
I'm trying to filter only those document who has created_by_id not [].
This is schema.
var CampaignSchema = new Schema({
name: { type: String, required: true },
description: { type: String, required: true },
budget: { type: String, required: true },
tags: { type: [ String ], required: true },
status: { type: Number },
payment_id: { type: String },
created_by_id: [{ type: Schema.Types.ObjectId, ref: 'User' }],
attached_file: {
uploaded_on: { type: Date, default: Date.now },
uploaded_by: { type: String, required: true },
},
added_url: {
added_on: { type: Date, default: Date.now },
added_by: { type: String, required: true },
},
updated_by: { type: String },
created_on: { type: Date, default: Date.now },
updated_on: { type: Date }
});
This is code:
_getCampaigns(req, res){
var token = helpersMethods.getToken(req.headers);
var page = parseInt(req.query.page) || 0; //for next page pass 1 here
var limit = parseInt(req.query.limit) || 10;
var term = new RegExp(req.query.search, 'i');
var obj = { "created_by_id": { "$ne": [] } };
if (token) {
Campaign.find(obj)
.populate({
path : 'created_by_id',
match : {
$or: [
{ name: { $regex: term }},
]
}
})
.sort({ updateAt: -1 })
.skip(page * limit)
.limit(limit)
.exec((err, doc) => {
if (err) {
return res.json(err);
}
Campaign.count(obj).exec((count_error, count) => {
if (err) {
return res.json(count_error);
}
return res.json({
total: count,
page: page,
pageSize: doc.length,
campaigns: doc
});
});
});
} else {
return res.status(403).send({success: false, msg: 'Unauthorized.'});
}
}
And i'm getting postman output like this, but i do not want the object who don't have created_by_id array:
{
"total": 2,
"page": 0,
"pageSize": 2,
"campaigns": [
{
"attached_file": {
"uploaded_by": "Demo user",
"uploaded_on": "2019-01-29T11:07:27.475Z"
},
"added_url": {
"added_by": "Demo user",
"added_on": "2019-01-29T11:07:27.475Z"
},
"tags": [
"tag1",
"tags2"
],
"_id": "5c5033ef28f63c72808f2225",
"created_by_id": {
"_id": "5c4965d477e7191c4d40b412",
"name": "Demo user",
"email": "demo#arth.tech",
"phone": "9918XXXXXX",
"type": "1",
"admin_rights": "1",
"password": "$2a$10$6T2ulNN60fBG9/vFgf8XhetkcWb/2zDxGXUMXMRi2Bltn8s1NEkbq",
"__v": 0,
"createdAt": "2019-01-24T07:31:03.327Z",
"loggedIn_at": "2019-01-30T06:33:04.388Z",
"loggedOut_at": "2019-01-24T08:03:44.091Z"
},
"name": "Test Campaign",
"description": "Discription of test campaign",
"budget": "2000",
"updated_by": "Demo User",
"created_on": "2019-01-29T11:07:27.475Z",
"__v": 0
},
{
"attached_file": {
"uploaded_by": "Demo User",
"uploaded_on": "2019-01-29T13:08:48.021Z"
},
"added_url": {
"added_by": "Demo user",
"added_on": "2019-01-29T13:08:48.021Z"
},
"tags": [
"test1",
"test2"
],
"_id": "5c505060b97f871123d97990",
"created_by_id": [],
"name": "Hello Campaign",
"description": "Description of Hello campaign",
"budget": "1000",
"updated_by": "Hello user",
"created_on": "2019-01-29T13:08:48.021Z",
"__v": 0
}
]
}
I want only those objects who has created_by_id, the actual output i want.
{
"total": 1,
"page": 0,
"pageSize": 1,
"campaigns": [
{
"attached_file": {
"uploaded_by": "Demo user",
"uploaded_on": "2019-01-29T11:07:27.475Z"
},
"added_url": {
"added_by": "Demo user",
"added_on": "2019-01-29T11:07:27.475Z"
},
"tags": [
"tag1",
"tags2"
],
"_id": "5c5033ef28f63c72808f2225",
"created_by_id": {
"_id": "5c4965d477e7191c4d40b412",
"name": "Demo user",
"email": "demo#arth.tech",
"phone": "9918XXXXXX",
"type": "1",
"admin_rights": "1",
"password": "$2a$10$6T2ulNN60fBG9/vFgf8XhetkcWb/2zDxGXUMXMRi2Bltn8s1NEkbq",
"__v": 0,
"createdAt": "2019-01-24T07:31:03.327Z",
"loggedIn_at": "2019-01-30T06:33:04.388Z",
"loggedOut_at": "2019-01-24T08:03:44.091Z"
},
"name": "Test Campaign",
"description": "Discription of test campaign",
"budget": "2000",
"updated_by": "Demo User",
"created_on": "2019-01-29T11:07:27.475Z",
"__v": 0
}
]
}
can any one help?
I did , what i want. here is updated code.
_getCampaigns(req, res){
var token = helpersMethods.getToken(req.headers);
var page = parseInt(req.query.page) || 0; //for next page pass 1 here
var limit = parseInt(req.query.limit) || 10;
var term = new RegExp(req.query.search, 'i');
var obj = {};
if (token) {
Campaign.find(obj)
.populate({
path : 'created_by_id',
match : {
$or: [
{ name: { $regex: term }},
]
}
})
.sort({ updateAt: -1 })
.skip(page * limit)
.limit(limit)
.exec((err, docs) => {
if (err) {
return res.json(err);
}else{
docs = docs.filter(function(doc) {
return doc.created_by_id.length != 0;
});
Campaign.count(obj).exec((count_error, count) => {
if (err) {
return res.json(count_error);
}else{
return res.json({
total: count,
page: page,
pageSize: docs.length,
campaigns: docs
});
}
});
}
});
} else {
return res.status(403).send({success: false, msg: 'Unauthorized.'});
}
}

Resources