how to write JOIN query in node.js sequalize? - node.js

I am executing join query in node.js using sequelize . How to write join queries using sequelize ? thank you in advance. have a good day.

You first need to define associations between your models. If I have two models User and Customers, I can define and association like this
User.belongsTo(Customer);
Customer.hasMany(User);
Then when you query you can join by specifying include in the options
Customer.finOne({
where: {
id: 1,
},
include: {
model: User,
where: {
id: 4,
}
}
}

Related

Prisma Connect Relationship While Creating

I'm trying to create a new entry into my table that has a relationship called "organizationAdmins". In that relationship is another relationship called "Role". I need to look up Role based on some criteria to connect. I've tried many different iterations to get this to work but the best I have is this, which doesn't work unfortunately...
let current_organization = await prisma.organization.create({
data: {
name: organization.name,
organizationAdmins: {
create : [{
account_id: account_id,
Role: {
connect : {
where: {name:"OWNER", owner:1, role:1, write:1, read:1}
}
}
}]
}
},
});
So if I were to take the SQL example for what I'm trying to do it would be this...
select id from role where name='OWNER' and owner=1 and role=1 and write=1 and read=1
I could pull the role_id like I did for account_id separately. But I'm trying to use prisma do the work for me so that we don't have multiple queries going on (less efficient). Welcome any thoughts here.

Sequelize - JOIN query table with AND operator

I'm using sequelize to handle SQLite database used by Electon app. Application let the user search for music based on selected topics, moods and so on.
I'm trying to build search mechanism that allow to select multiple moods and the function should return tracks that have all of the selected moods
Here is mentioned above database simplified model:
Also the sequelize relation between models are set
db.moods.belongsToMany(db.tracks, {
through: db.moodsTracks,
foreignKey: 'uuid',
});
db.tracks.belongsToMany(db.moods, {
through: db.moodsTracks,
foreignKey: 'trackId',
});
db.moods.hasMany(db.moodsTracks, {foreignKey: 'uuid'});
db.tracks.hasMany(db.moodsTracks, {foreignKey: 'trackId'});
Now I'm trying to find all tracks that contain has specific moods
let tracks = await db.tracks.findAll({
include: [{
model: db.moods,
required: true,
where: uuid: {
[Op.and]: ['MOOD-UUID-1', 'MOOD-UUID-2']
}
}],
})
(first try fail)
I have tried to log generated by sequelize code and its returns:
INNER JOIN `moodsTracks` AS `moodsTracks` ON `tracks`.`id` = `moodsTracks`.`trackId`
AND (
`moodsTracks`.`uuid` = 'MOOD-UUID-1'
AND `moodsTracks`.`uuid` = 'MOOD-UUID-2'
)
Then I have try to build raw SQLite query
SELECT
COUNT(trackid),
*
FROM
`tracks` AS `tracks`
INNER JOIN `moodstracks` AS `moodsTracks` ON `tracks`.`id` = `moodstracks`.`trackid`
WHERE
(
`moodsTracks`.`uuid` = 'MOOD-UUID-1'
OR `moodsTracks`.`uuid` = 'MOOD-UUID-2'
)
GROUP BY
(`moodsTracks`.`trackId`)
HAVING
COUNT(trackid) = 2;
I'm aware that isn't great solution, but it works in SQL console.
Questions:
Is there any other way to solve that kind problem? Maybe I use AND operator wrongly
If not, I will try to implement that SQL code above.
Is there any documentation for HAVING keyword in sequelize, i didn't found any thing like this on official web page
Why are you using [Op.and] when in your raw query you are using 'OR'?
This solution works for me:
let tracks = await db.tracks.findAll({
include: [db.moods],
group: 'moodsTracks.trackId',
include: [{
model: db.moods,
where: {
uuid:['UUID1', 'UUID2']
},
having: ["COUNT(DISTINCT moodsTracks.uuid) = 2"]
}]
})

Sequelize : Get Subquery/Raw Query as model for include

I have gone through the Sequelize doc, but can't find anything helpful
What I want to do is to add raw query or custom model in include, is it possible ?
model.Post.findAll({
include: [{
model: model.User,
attributes: ['fullname', 'profilepic'],
},
{
model: model.PostComments,
},
{
model: "Raw Query"
}
]
}
What I want to achieve is like :
Select post_id, count(*) as total_likes from post_likes group by post_id
I can't achieve this by using simply include, so what I want to do is create a table/model from above query and then use it inside include.
If I use group by withing include it gives group by from top level, and I want to apply group by just for the post_like table.
Please let me know, if it found confusing or not clear.
I was looking to do the same, use a raw query dynamically formed inside the include but there's no possible way to use include without a model https://sequelize.org/master/class/lib/model.js~Model.html#static-method-findAll .
For the purposes of my MySQL I turned my inner join (include) into a where in. I was doing the inner join to avoid the exception This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery . I get this exception because I have a subquery with LIMIT applied.
If it helps anyone:
let rows = await j_model.findAll({
attributes: [...j_columns, `${association}.meta_key_id`],
include: [
{
model: um_model,
as: association,
attributes: ['um_id'],
on: {'j_id' : {$col: 'j.j_id'} }
],
where: {'j_id': {$in: sequelize.literal(`(SELECT * FROM (${massive_inner_raw_query}) as tmp)`)}},
logging: console.log
});
The actual magic is in this line:
where: {'j_id': {$in: sequelize.literal(`(SELECT * FROM (${massive_inner_raw_query}) as tmp)`)}}
The SELECT * FROM removes that exception and lets me do a where in instead of the wanted INNER JOIN. Maybe you can apply a similar deal to your problem.
You can use
Model.findAll({
attributes: [[models.sequelize.literal('CASE WHEN "field1" = true THEN 55
ELSE 23 END'), 'field3']]
}
OR
Model.findAll({
attributes: { include: [[models.sequelize.literal('CASE WHEN "field1" = true THEN 55 ELSE 23 END'), 'field3']]}
}

Multiple relation n:n to one table in sequelize

I am using Sequelize for PostgresSQL. For example: I've got two tables Friendship and User. To make friendship possible for every user, I've got two relations n:n.
Associations in Sequelize
User.hasMany(Friendship,
{
as: "friendshipsAsked",
foreignKey: "asked_user_id",
joinTableName: "friendship"
});
User.hasMany(Friendship,
{
as: "friendshipsAsking",
foreignKey: "asking_user_id",
joinTableName: "friendship"
});
Friendship.belongsTo(User,
{
...
});
Friendship.belongsTo(User,
{
...
});
My biggest problem is querying friendships for user. When I've got user model, I have to get user.getFriendshipsAsking() and user.getFriendshipsAsked() and then merge both.
Is there any possibility to change relations so I can have user.getFriendships() in SQL such that it will perform like SELECT * FROM frienships WHERE requesting_user_id = 'user.id' OR requested_user_id = 'user.id'?
I would like to have a better solution to model friendship between users in the database?

How to add query logic to graphql-sequelize based setup?

Here is a simple scenario
I want to query GraphQL and fetch all the students that have attended school more then 200 days this year.
I have a Student sequelize model, a matching GraphQL Object, a students Query which accepts the days int as an argument { students(days:200) }
What I'm obviously trying to do is to implement the logic "get all students where school_visits counter is greater than 200" just as an example...
I'm using graphql-sequelize to glue between sequelize and GraphQL.
a simple example query definition looks like this:
students: {
type: new GraphQLList(Student),
args:{
id : {type:GraphQLInt},
days: {type:GraphQLInt}
},
resolve: resolver(models.Student)
}
as you can notice, this structure doesn't allow me to insert some logic to the query...
If you had any experience working with GraphQl and Sequelize - this is a very generic situation... I'd appreciate any help resolving it.
Cheers
Ajar
Looking at the Sequelize docs, you can try doing something like this in the students resolve function:
resolve(root, args) {
// Assuming you've imported your model
return Db.models.student.findAll({
where: {
days: {
// greater than
$gt: args.days
}
}
});
}

Resources