How to sort by column? - node.js

When I sort by role_name column, this error occurs:
column users.role_name does not exist
If sort by any other column, then there will be no problems. How to sort by column for which join is performed?
module.exports.getAll = async function (req, res) {
try {
const query = {
where: {
[Op.or]: [
{
full_name: {
[Op.iLike]: `%${req.query.search}%`
}
},
{
username: {
[Op.like]: `%${req.query.search}%`
}
},
Sequelize.where(Sequelize.col((Roles, "role_name"), "varchar"), {
[Op.like]: `%${req.query.search}%`
})
]
},
include: [{
model: Roles,
attributes: ["role_name"],
required: true
}],
offset: +req.query.pageSize * (+req.query.page - 1),
limit: +req.query.pageSize,
order: [
[req.query.sort, req.query.order]
]
};
const users = await Users.findAndCountAll(query);
res.status(200).json(users);
} catch (e) {
errorHandler(res, e);
}
};
If add to include:
order: [
[Roles, req.query.sort, req.query.order]
]
then it does not work. And if add this after include, it will not be possible to sort by the remaining columns.

Related

I can't use session in nodejs. how can i make safe listing?

In my project that I created using nextjs, I want the session to list while I make a listing query on the backend. If there is no session, I want it not to give authorized permission. I am using next authentication. I can't pull next in session But I can't get session. Can you help me, please?
Offers.belongsTo(Users, {as: 'User', foreignKey: 'user_id'});
router.post('/api/logistic/offers/get-offers', async (req, res) => {
const {limit, page, sortColumn, sortType, search, session} = req.body;
if(session){
const total = await Offers.findAll();
const offersList = await Offers.findAll({
limit: limit,
offset: (page - 1) * limit,
order: [
[sortColumn, sortType]
],
where: {
[Op.or]: [
{
offers_no: {
[Op.substring]: [
search
]
}
},
{
agreement_date: {
[Op.substring]: [
search
]
}
},
{
routes: {
[Op.substring]: [
search
]
}
},
{
type_of_the_transport: {
[Op.substring]: [
search
]
}
},
]
},
include: [{
model: Users,
as: 'User'
}]
});
res.json({
total: total.length,
data: offersList
});
}else {
res.status(401).send(JSON.stringify({
status: "error",
title: 'Unauthorized',
message: 'Unauthorized'
}));
}
})
The error I get in the terminal is always like this. I can't use session
//offers list
Offers.belongsTo(Users, {as: 'User', foreignKey: 'user_id'});
router.post('/api/logistic/offers/get-offers', async (req, res) => {
const session = await getSession({req});
console.log(session);
if(session){
const {limit, page, sortColumn, sortType, search} = req.body;
const total = await Offers.findAll();
const offersList = await Offers.findAll({
limit: limit,
offset: (page - 1) * limit,
order: [
[sortColumn, sortType]
],
where: {
[Op.or]: [
{
offers_no: {
[Op.substring]: [
search
]
}
},
{
agreement_date: {
[Op.substring]: [
search
]
}
},
{
routes: {
[Op.substring]: [
search
]
}
},
{
type_of_the_transport: {
[Op.substring]: [
search
]
}
},
]
},
include: [{
model: Users,
as: 'User'
}]
});
res.json({
total: total.length,
data: offersList
});
}else {
res.status(401).send(JSON.stringify({
status: "error",
title: 'Unauthorized',
message: 'Unauthorized'
}));
}
})
This is how my code was before. but it didn't work.

Counting number of associated rows in sequelize

I am trying to find the count of students inside the classStudents association. Here teacher_details table is connected to class_details tables using 'section'
association and class_details tables is connected to student_details table using 'classStudents' association. I have tried the below method but got error ==>
Unknown column 'section->classStudents.studentId' in 'field list'
please let me know the correct procedure to count the associated students count
const getAssignedDetails = async (req, res) => {
try {
const assignedDetails = await Entity.teacherAssignedDetail.findAll({
where: { status: 1, teacherId: req.teacherId },
attributes: [
'role',
[
Sequelize.fn(
'COUNT',
Sequelize.col('section.classStudents.studentId')
),
'studentCount',
],
],
include: [
{
association: 'section',
attributes: ['sectionId', 'className', 'classEmoji'],
include: [
{
association: 'classStudents',
where: { status: 1 },
required: false,
},
],
where: { status: 1 },
},
{
association: 'subjectDetails',
attributes: [['id', 'masterSubjectId'], 'subjectName'],
},
],
});
res.json({
responseCode: 0,
responseMessage: 'Success',
responseData: assignedDetails,
});
} catch (err) {
res.status(500).send(errorHandling(err.message));
}
};

Sequelize Complex Filter | Node.js

i want to filter, but that depend to the user, for example
Data.findAll({
where: {
name: {
[Op.or]: [
{ [Op.like]: ['%samsung%'] },
{ [Op.like]: ['%iphone%'] },
{ [Op.like]: ['%alcatel%']}
]
}
}
}
If the user selects only Samsung, how do I go about filtering only by Samsung?
Assuming req.query.brands stores either a single search string or an array of strings we can build Op.or conditions on the fly:
const brands = [].concat(req.query.brands)
const brandConditions = brands.map(x => ({
[Op.like]: `%${x}%`
})
const foundItems = await Data.findAll({
where: {
name: {
[Op.or]: brandConditions
}
}
}

Mongoose multiple optional 'and' conditions

I am trying to filter a collection with 3 optional 'and' conditions.
Here is my model:
const Company = mongoose.model(
'Company',
new Schema({
name: { type: String },
sectors: [{ type: Schema.Types.ObjectId, ref: 'Sector' }],
industries: [{ type: Schema.Types.ObjectId, ref: 'Industry' }],
countries: [{ type: Schema.Types.ObjectId, ref: 'Country' }],
})
And my component:
const getCompanies = (skip, limit, filter) =>
Company.find({
...filter.countries && { countries: filter.countries },
...filter.sectors && { sectors: filter.sectors },
...filter.industries && { industries: filter.industries },
})
.skip(skip)
.limit(limit)
.sort({ date: -1 })
.populate('countries')
.populate('sectors')
.populate('industries');
const getAll = async (req, res) => {
try {
const countries = req.query.country;
const sectors = req.query.sector;
const industries = req.query.industry;
const skip = parseInt(req.query.skip, 10);
const limit = parseInt(req.query.limit, 10);
const filter = {
...countries && { countries },
...sectors && { sectors },
...industries && { industries },
};
const result = await getCompanies(skip, limit, filter);
return res.status(200).json(result);
} catch (e) {
return res.status(500).send({ message: (e.message) });
}
};
This is working when the filter is empty, but when there is one or more items in the filter, I get an empty array.
If I hard code data in getCompanies like so:
Company.find({
countries: '5d5e913e20c01070fef5c77e',
sectors: '5d5e913e20c01070fef5c754',
industries: '5d5e913e20c01070fef5c7ad',
})
or :
Company.find({
countries: '5d5e913e20c01070fef5c77e'
})
I get the data I want.
I also tried to console.log the filter in getCompanies to make sure the data was correct, and I get this if all fields are requested:
{
countries: '5d5e913e20c01070fef5c77e',
sectors: '5d5e913e20c01070fef5c754',
industries: '5d5e913e20c01070fef5c7ad',
}
and this for just one:
{ countries: '5d5e913e20c01070fef5c77e' }
So it seems fine to me.
I also tried using '$and' like so:
Company.find({ $and: [
{ ...filter.countries && { countries: filter.countries } },
{ ...filter.sectors && { sectors: filter.sectors } },
{ ...filter.industries && {industries: filter.industries } },
],
})
or using '$in':
Company.find({
...filter.countries && { countries: { $in: filter.countries } },
...filter.sectors && { sectors: { $in: filter.sectors } },
...filter.industries && { industries: { $in: filter.industries } },
})
But no luck either.
Here is a sample URL:
GET /api/internal/member/get?skip=12&limit=6&country=5d5e913e20c01070fef5c77e&sector=&industry=
I have found some other threads with questions somewhat similar to mine, but they were to different to help me solve my case.
Looking forward to your helpful advice.
I finally got it to work. Turns out I was not clearing the data in the frontend at each change, which caused an issue with the skip/limit fields.
I also changed the find as advised by #whoami like so:
Company.find({ $and: [
{
...filter.countries && { countries: { $in: [mongoose.Types.ObjectId(filter.countries)] } },
...filter.sectors && { sectors: { $in: [mongoose.Types.ObjectId(filter.sectors)] } },
...filter.sdgs && { sdgs: { $in: [mongoose.Types.ObjectId(filter.sdgs)] } },
}
],
})

mongoDB find, update and pull in One Query

I want to do all the find the data from the collection and then want to update some field as well as depending on want to empty the array.
const addCityFilter = (req, res) => {
if (req.body.aCities === "") {
res.status(409).jsonp({ message: adminMessages.err_fill_val_properly });
return false;
} else {
var Cities = req.body.aCities.split(","); // It will make array of Cities
const filterType = { "geoGraphicalFilter.filterType": "cities", "geoGraphicalFilter.countries": [], "geoGraphicalFilter.aCoordinates": [] };
/** While using $addToset it ensure that to not add Duplicate Value
* $each will add all values in array
*/
huntingModel
.update(
{
_id: req.body.id,
},
{
$addToSet: {
"geoGraphicalFilter.cities": { $each: Cities }
}
},
{$set:{filterType}},
).then(function(data) {
res.status(200).jsonp({
message: adminMessages.succ_cityFilter_added
});
});
}
};
Collection
geoGraphicalFilter: {
filterType: {
type:String,
enum: ["countries", "cities", "polygons"],
default: "countries"
},
countries: { type: Array },
cities: { type: Array },
aCoordinates: [
{
polygons: { type: Array }
}
]
}
But as result, the only city array is getting an update. No changes in filterType.
You appear to be passing the $set of filterType as the options argument, not the update argument.
huntingModel
.update(
{
_id: req.body.id,
},
{
$addToSet: {
"geoGraphicalFilter.cities": { $each: Cities }
},
$set: {
filterType
}
}
).then(function(data) {
res.status(200).jsonp({
message: adminMessages.succ_cityFilter_added
});
});

Resources