When using a literal with Sequelize (v4 or v5) you cannot tell Sequelize to cast your value to boolean directly, is it possible to cast it in another way ?
Example :
models.Publication.findAll({
attributes: {
include: [
[models.sequelize.literal("IFNULL((Select 1 from `like` where like.publicationId = `Publication`.`publicationId` and userId = " + req.decoded.userId + "), 0)"), 'liked'],
]
},
order: [['createdAt', 'DESC']],
})
I could use the map function but I have a lot of data and it will slow my function.
Related
I want to get id of affected row in update action using Sequlaize.update method.
const result = await Voucher.update(
{
used: "1",
},
{
where: {
voucher_group_id: 5,
used: "0",
},
limit: 1,
returning: true,
}
);
when I set returning to true, the result was [null, 1]. but the affected row id is other value like: 72
The returning option is only for the Postgres dialect, as specified in the Sequelize v6 Documentation for Model#update.
If you are using a Dialect like MySQL, you could load in the record you want to update via Model#findOne first and then use instance#update.
const voucher = await Voucher.findOne({
where: {
voucher_group_id: 5,
used: "0"
}
});
// voucher is potentially null at this point
voucher.update({ used: "1" });
Side note: If your used field on your Voucher model is a boolean, you can use true/false and Sequelize will automatically convert these to the tiny int equivalent values for your dialect.
In my mysql table ,i have a column of JSON type
const monthlyProgress = sequelize.define("monthlyprogress", {
.
.
.
duration: {
type: Sequelize.JSON
}
});
return monthlyProgress;
in this "duration" column i have a JSON array of objects
[{"time":"nov-2020"},{"time":"dec-2020"}]
Now i need a sequelize findall to fetch the rows where the condition will e
time = "nov-2020" of that "duration" column
i have tried i many ways but failed everyime. Below i am showing one of the ways that i found on stackoverflow. But its also a failed attepmt
Its giving me output of those rows who doesnt have time="nov-2020"
await monthlyProgress.findAll({
where: {
duration: [
fn('JSON_CONTAINS', col('duration'), cast('{"time": "nov-2020"}', 'CHAR CHARACTER SET utf8'))
]
}
})
It's another attempt thats is showing this error message UnhandledPromiseRejectionWarning: ReferenceError: JSON_CONTAINS is not defined
await monthlyProgress.findAll({
where: {
[Op.and]: db.Sequelize.literal(JSON_CONTAINS(`duration`, '{\"time\": nov-2020}')),
}
})
I want to compare some case sensitive string data using sequelize. my string is "HARSH" and in db, it is "harsh" which should not be equal. I'm using where condition to find the data "HARSH" but in the response, I'm getting string data "harsh".
pReadings.user_model.findAll({
where: {
firstname: "HARSH"
}
})
The collation on the column needs to be ..._bin. It is probably ..._ci, meaning "case insensitive". It was either set that way by default or explicitly.
Please provide SHOW CREATE TABLE for assistance in changing it.
// search case insensitive nodejs usnig sequelize
const sequelize = require('sequelize');
let search = "testData"; // what ever you right here
pReadings.user_model.findAll({
where: {
firstname: sequelize.where(sequelize.fn('LOWER', sequelize.col('firstname')), 'LIKE', '%' + search.toLowerCase() + '%')
}
})
Try using the following,
pReadings.user_model.findAll({
where: sequelize.where(sequelize.fn('BINARY', sequelize.col('firstname')), 'HARSH')
// SELECT * FROM your_table WHERE BINARY(firstname) = 'HARSH';
})
For more information, check out Querying - Sequelize, under heading "Where > Basics". Good luck!
Your query is right. There is no problem with your query.
You could also try:
pReadings.user_model.findAll({
where: {
firstname: { $eq: 'HARSH' }
}
})
I am using the sequelize ORM for a node.js project I am working on. One query I have, I need to perform a like operation on the concatenated result of multiple columns.
For instance, something like the following:
SELECT * FROM People WHERE (CONCAT(firstname, ' ', lastname)) LIKE '%John Do%'.
I am using the following syntax and would like to know if this is possible without having to resort to using RAW queries (which is nowhere else in my solution).
var criteria = {
include: [
occupation
],
where: {
is_active: 1
},
nest: false
};
db.people.findAll(criteria, {}).then(function(people) {
success(people);
}).catch(function(err) {
error(err);
});
Any ideas?
You'll need something like this
var criteria = {
where: Sequelize.where(Sequelize.fn("concat", Sequelize.col("firstname"), Sequelize.col("lastname")), {
like: '%John Do%'
})
}
Note: untested
Original source
Inspired by #code-jaff but you need to concatenate a space string in between first and last names to make this work correctly. Otherwise it would only return for 'JohnDoe' and not for 'John Doe'. Here's the code.
Sequelize.where(Sequelize.fn('concat', Sequelize.col('firstName'), ' ', Sequelize.col('lastName')), {
like: '% John Doe %'
})
To provide some context for people who might not understand where this would fit into your query, this is an example of the above code in a where or statement. req.body.query being the variable search term that you're POSTing.
Users.findAll({
where: {
$or: [
Sequelize.where(Sequelize.fn('concat', Sequelize.col('firstName'), ' ', Sequelize.col('lastName')), {
like: '%' + req.body.query + '%'
}),
{ email: { $like: '%' + req.body.query + '%' } },
{ companyName: { $like: '%' + req.body.query + '%' } }
]
}
})
Update for Sequelize 4.0
String based operators ($like and $or in the above example) have been deprecated in favour of symbol based operators. It's a good thing for security
See: http://docs.sequelizejs.com/manual/tutorial/querying.html#operators
These operators would be replaced with [Sequelize.Op.like] and [Sequelize.Op.or]. There are also other ways to configure it in your sequelize options highlighted in their documentation
I was able to achieve this with the new sequelize version 5.21.13 based on #yjimk answer.
Users.findAll({
where: {
[sequelize.Op.or]:{
namesQuery: sequelize.where(
sequelize.fn(
"concat",
sequelize.col("firstName"),
" ",
sequelize.col("lastName")
),
{
[sequelize.Op.like]: `%${req.body.query}%`,
}
),
email: {[sequelize.Op.like]: `%${req.body.query}%`},
companyName: {[sequelize.Op.like]: `%${req.body.query}%`},
}
})
db.models.users.findOne({
where: {
[db.sequelize.Op.and]: [
db.sequelize.where(
db.sequelize.fn('CONCAT', db.sequelize.col('first_name'), ' ', db.sequelize.col('last_name')),
{ like: `%${name}%` },
),
{ status: 'ACTIVE' },
]
}
});
I have a query I'm trying to perform based on a one to many relationship.
As an example there is a model called Users and one called Projects.
Users hasMany Projects
Projects have many types which are stored in a type (enum) column. There are 4 different types that potentially a user may have that I want to load. The catch is I want to include the most recent project record (createdAt column) for all networks that potentially will be there. I have not found a way to structure the query for it to work as an include. I have however found a way to do a raw query which does what I want.
I am looking for a way without having to do a raw query. By doing the raw query I have to map the returned results to users I've returned from the other method, or I have to do a simple include and then trim off all the results that are not the most recent. The latter is fine, but I see this getting slower as a user will have many projects and it will keep growing steadily.
This allow serialize a json for anywhere action about a model. Read it, very well
sequelize-virtual-fields
// define models
var Person = sequelize.define('Person', { name: Sequelize.STRING });
var Task = sequelize.define('Task', {
name: Sequelize.STRING,
nameWithPerson: {
type: Sequelize.VIRTUAL,
get: function() { return this.name + ' (' + this.Person.name + ')' }
attributes: [ 'name' ],
include: [ { model: Person, attributes: [ 'name' ] } ],
order: [ ['name'], [ Person, 'name' ] ]
}
});
// define associations
Task.belongsTo(Person);
Person.hasMany(Task);
// activate virtual fields functionality
sequelize.initVirtualFields();