Sequelize - How to search range in multiple columns? - mysql

Mysql Query :
SELECT
* FROM
advisor_product_range WHERE 5 BETWEEN from_range AND to_range;
How to replicate the same in sequelize format
const AdvisorProductRangeDataGdp = await AdvisorProductRange.findAll({
attributes: ['office_id','yyyymmdd','product_type','from_range','to_range','amount_per_order'],
where: {
from_range: {
[dbOp.gte]: gdpCount
},
to_range: {
[dbOp.lte]: gdpCount
}
}
});
OUTPUT OF THIS QUERY IN MYSQL TERMS :
> SELECT `office_id`, `yyyymmdd`, `product_type`, `from_range`,
> `to_range`, `amount_per_order` FROM `advisor_product_range` AS
> `AdvisorProductRange` WHERE `AdvisorProductRange`.`from_range` <= 5 AND
> `AdvisorProductRange`.`to_range` >= 5;
Mysql Table Structure :
Version : sequelize :5.8

Issue was found out its was related to the operator used in the query
was switch in the incorrect way .
const AdvisorProductRangeDataGdp = await AdvisorProductRange.findAll({
attributes: ['office_id','yyyymmdd','product_type','from_range','to_range','amount_per_order'],
where: {
from_range: {
[dbOp.lte]: gdpCount
},
to_range: {
[dbOp.gte]: gdpCount
}
}
});

Related

Convert Mysql to Sequelize ORM

how to convert this sql to sequelize ORM?
SELECT *
FROM `verses`
WHERE (surah_id, verse_latin_number) >= (112, 2)
AND (surah_id, verse_latin_number) <= (114, 3);
Are "surah_id" and "verse_latin_number" 2 columns of the table "verses" ?
If yes:
const db = require('...mydatabase.js')
const { Op } = require('sequelize')
db.Verses.findAll({
where: {
[Op.and]: [
{ surah_id: {[Op.gte]:112} },
{ surah_id: {[Op.lte]:114} },
{ verse_latin_number: {[Op.gte]:2} },
{ verse_latin_number: {[Op.gte]:3} }
]
})

Sequelize - query other table inside where clause

I am trying to do something and do not know if this is possible with sequelize. Basically I have this code snippet running on graphQl and basically what this does is to find kits on the kits table and then verify if the same id exists on the "users" table. If not, it returns them, if yes it does not. However now we need to scale this to have pagination and the current snippet is not so scalable. That is why I had the idea to just include the for loop in the where clause or somehow to check there, but really do not know any command on mySql that allows to do this.
Do you have any tip?
async findKitsWithResultNoReg2(_, {search}) {
try {
let promises = []
const a1 = await db.kits.findAll({
where: {
[Op.and]: [
{ result: { [Op.or]: [1, 2, 3] } },
{ cp: 0 },
{[Op.or]: [
{ kitID: { [Op.like]: '%' + search + '%' } }]}
]
}
})
for (let i = 0; i < a1.length; i++) {
const a2 = await db.users.findByPk(a1[i].dataValues.kitID)
if (a2 === null) {
const a3 = {
kitID: a1[i].dataValues.kitID,
result: a1[i].dataValues.result,
date: a1[i].dataValues.resultDate
}
promises.push(a3)
}
}
return Promise.all(promises)
} catch (error) {
console.log(error)
}
},
async findKitsWithResultNoReg() {
try {
const a0 = await sequelize.query(`SELECT kitID, result, resultDate from kits where result in (1,2,3) and cp = 0 and archived = 0 and not Exists(select kitID from users where kits.kitID = users.kitID) order by resultDate desc`, { type: QueryTypes.SELECT })
const a1 = JSON.stringify(a0)
return a1
} catch (error) {
console.log(error)
}
},

Sequelize : How to check if a substring exists in a table

Is there a way to check if a particular string exists in a column in a table?
For example, I have a table 'fruits' with two columns, primary key and fruit_name and following rows
1 apple
2 orange
3 pineapple
I have a sample string named apple_shake. I need to check if a substring of this apple_shake exists. The query should return row containing 'apple'
I know how this can be done in mysql query - SQL - Query to find if a string contains part of the value in Column
But through sequelize, following has problem
var sample_fruit_string = "apple_shake";
var gsp_config = await model.fruit.findOne({where: {
fruit_name: {
[Op.like]: sample_fruit_string + '%'
}
}});
Credit to #alx for the SQL I didn't know was possible - this is how you generate the appropriate SQL with Sequelize. Note that this may not be efficient with large datasets.
const sample_fruit_string = "apple_shake";
const gsp_config = await model.fruit.findOne({
attributes: ['id'],
where: Sequelize.where(
Sequelize.fn('LOCATE', Sequelize.col('fruit_name'), sample_fruit_string),
Sequelize.Op.ne,
0
),
logging: true,
});
Generates the following:
SELECT `id` FROM `fruit` AS `fruit` WHERE LOCATE(`fruit_name`, 'apple_shake') != 0 LIMIT 1;
Sequelize has a substring operator which you could use directly to solve this.
var sample_fruit_string = "apple_shake";
var gsp_config = await model.fruit.findOne({where: {
fruit_name: {
[Op.substring]: sample_fruit_string // LIKE '%sample_fruit_string%'
}
}});
var sample_fruit_string = "apple_shake";
var gsp_config = await model.fruit.findOne({where: {
fruit_name: {
[Op.like]: `%${sample_fruit_string}%` // LIKE '%sample_fruit_string%'
// [Op.ilike]: `%${sample_fruit_string}%` // For case sensitive searching
// [Op.substring]: sample_fruit_substring // Has been depreciated in future version of sequelize.
}
}});

sequelize between operator not working properly

I am trying to do query to get all rows between id 1 to 4.
I am using mySQL and sequelize.
query
`
main.test = function(req,res,next)
{
var param = req.params;
model.Time.find({
where:{
id:{
$between:[1,4]
}
},limit: 10
}).then(function (time) {
console.log("Time"+time);
});
}
`
and getting the result when execute
Need a way solve it?

Sequelize - case-insensitive like

How can I achieve this in Sequelize?
SELECT * FROM table where lower(column) LIKE ('abcd%');
I can't find a way to mix lower function with $like
You should use Sequelize.Op :
Table.findAll({
where: {
name: {
[Sequelize.Op.iLike]: searchQuery
}
}
})
Don't forget to add % before or after your searchQuery, if you want to make a partial query.
See the docs here
I found the solution:
Table.findAll({
attributes: ['createdAt', 'col'],
where: {
$and:[
{
createdAt:{
$between:[minDate, maxDate]
}
},
Sequelize.where(
Sequelize.fn('lower', Sequelize.col('col')),
{
$like: 'abcd%'
}
)
]
}
});
If you're using PostGres, you can use the $iLike operator to search rows (NOT column names like your question asks).
Sequelize Docs
While it doesn't fully address your question, hopefully it will help someone down the road who searches for case-insensitive + Sequelize, which brought me here.
Table.findAll({
where: {
createdAt: {
$between: [minDate, maxDate]
},
someOtherColumn: {
$like: '%mysearchterm%'
}
}
})
I run into similar problem and solved by
const values = ['adcd'].map(x => x.toLowerCase());
const results = await SomeModel.findAll({
attributes: [
...Object.keys(SomeModel.rawAttributes),
[Sequelize.fn('LOWER', Sequelize.col('someColumn')), 'lower'],
],
having: { lower: values, },
});