mickhansen / graphql-sequelize

GraphQL & Relay for MySQL & Postgres via Sequelize
MIT License
1.9k stars 172 forks source link

Expressing associations in WHERE clause #583

Closed moseleyi closed 4 years ago

moseleyi commented 6 years ago

I'm onto the next stage :D

I'm building where in before function where I included one extra model, so at the moment I have two: User and UserDetail

search as an argument has been declared in the GraphQL Schema and now I'm trying to use the value to be searched on both levels. So far I tried this:

if(args.search != undefined) {
    options.where = {
        "$or" : [
              {
                   username : {
                         like : "%" + args.search + "%"
                   }
              },
             {
                   firstname : {
                        like : "%" + args.search + "%"
                   },
            }
        ]
    }
}

username is in User and firstname is in UserDetail model, but I can't figure out how to reference that model

Ideally I want to generate query like this:

SELECT 
    * 
FROM user 
    INNER JOIN user_detail on user.user_id = user_detail.user_id
WHERE
    user.username LIKE '%<search>%' OR
    user_detail.firstname LIKE '%<search>%'

Actually while I'm at it I might add another question. At the moment my query is actually more complicated, and it looks like this:

SELECT
    *
FROM (
    SELECT 
        * 
    FROM user 
        INNER JOIN user_detail on user.user_id = user_detail.user_id
    WHERE
        user.username LIKE '%<search>%' OR
        user_detail.firstname LIKE '%<search>%'
) AS "Users"
    LEFT OUTER JOIN Sample ON Sample.user_id = Users.user_id

The inner query, I presume, is created because of 1:1 "hasOne" model association. (I realised it's because of pagination and the COUNT(*) OVER query, but is it necessary?)

What if I wanted an OR statement that goes over both queries?

SELECT
    *
FROM (
    SELECT 
        * 
    FROM user 
        INNER JOIN user_detail on user.user_id = user_detail.user_id
) AS "Users"
    LEFT OUTER JOIN Sample ON Sample.user_id = Users.user_id
    WHERE
        Users.username LIKE '%<search>%' OR
        Users.firstname LIKE '%<search>%' OR
        Sample.name LIKE '%<search>%'

I understand the inner select would run across all the results but we are fine with that. What I can't figure out is how to build the syntax for Sequelize so that it goes on the outside of the inner query, and sometimes to the inner one.

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.