GraphQL: Querying for a list of object which have relationship to another object - graphql

I have set up my schema on GraphCMS and finding graphQL to be very convenient.
I have a workout object and a workoutCategory object. Those two are linked by a many to many relationship.
I'd like to write a query that allows me to get the list of workout which are part of a certain category.
I'm writing the query as follow:
workout(where:{ workoutCategories: { id: "xxxxxxx" } }) {
id
}
graphCMS gives me a syntax error on the workoutCategories which does not make sense to me yet
Field workout categories is not defined by type WorkoutWhereUniqueInput
What do I need to do to be able to achieve my goal?
Thanks in advance

Turns out I need to query on 'workouts' (see the 's' at the end) and not on 'workout'...

Related

Filtering a list of values by a field value in GraphQL

So I'm doing some tests with GraphQL, and I'm failing in doing something that I believe is fairly simple.
When going to the GraphQL demo site (https://graphql.org/swapi-graphql) I'm presented with a default query which goes like this:
{
allFilms {
films {
title,
director,
releaseDate
}
}
}
This works as expected and returns a list of films.
Now - I would like to modify this query to return only the films where the director is George Lucas, and for the life of me - I can't figure out how to do that.
I've tried using the where and filter expressions, and also change the second line to films: (director: "George Lucas") but keep getting error messages.
What's the correct syntax for doing that?
Thanks!
If you check the docs of the provided GraphQL schema, you'll see that this is not possible. Following is the definition of the allFilms field:
allFilms(
after: String
first: Int
before: String
last: Int
): FilmsConnection
As per the doc, it has 4 input arguments, which are after, first, before, and last. There is no way to filter this out using the director's name.
GraphQL is not SQL. You cannot use expressions like WHERE or FILTER in GraphQL. The schema is already defined and the filters are pre-defined too. If the schema does not allow you to filter values using a certain field, you just can't do it.
You can to see the graphql schema here https://github.com/graphql/swapi-graphql/blob/master/schema.graphql
The allFilms query does not contain a filter for the field director. Also i can't find other query with this filter.
Most likely you need to write a filter on the result of the query.

Loopback4 filter inside the scope return list still

I'm using lb4
I have some problems here, I try to find the list with where conditions inside the scope with pagination.
const teacherWithStudents = await this.teacherRepository.find({limit:10,skip:0,
include: [{
relation: "student",
scope: {
where: { "name": "some random name here" },
}
}]
})
The expected teacher's array is : [] (because I searched a random string in student name which is not in DB)
but I got teachers to array without student like this: [{teacherId:1,teacherName:"Stella"}{teacherId:2,teacherName:"Mery"}]
if I filter student names if no teacher has a student that I filtered I need an empty array but I get only a teacher.
I hope I explained the issue in detail.
Thanks in advance
This is expected as the parent and relation queries should be perceived as two separate queries.
First, the list of teachers based on the parent query are resolved. The IDs of the resolved teachers are then used as a constraint when querying for the list of students.
Both results are then combined together to create the final response.
Loopback uses left join. if you want to find only teachers where student is not null then you have to use inner join with native query.

Group queries in GraphQL (not "group by")

in my app there are many entities which get exposed by GraphQL. All that entities get Resolvers and those have many methods (I think they are called "fields" in GraphQl). Since there is only one Query type allowed, I get an "endless" list of fields which belong to many different contexts, i.E.:
query {
newsRss (...)
newsCurrent (...)
userById(...)
weatherCurrent (...)
weatherForecast(...)
# ... many more
}
As you can see, there are still 3 different contexts here: news, users and weather. Now I can go on and prefix all fields ([contextName]FieldName), as I did in the example, but the list gets longer and longer.
Is there a way to "group" some of them together, if they relate to the same context? Like so, in case of the weather context:
query {
weather {
current(...)
forecast(...)
}
}
Thanks in advance!
If you want to group them together , you need to have a type which contain all fields under the same context . Take weather as an example , you need to have a type which contain currentWeather and forecastWeather field. Does this concept make sense to your application such that you can name it easily and users will not feel strange about it ? If yes , you can change the schema to achieve your purpose.
On the other hand, if all fields of the same context actually return the same type but they just filtering different things, you can consider to define arguments in the root query field to specify the condition that you want to filter , something like :
query {
weather(type:CURRENT){}
}
and
query {
weather(type:FORECAST){}
}
to query the current weather and forecast weather respectively.
So it is a question about how you design the schema.

Adding limit's to nested value in graphql

Here's a simple graphQL query to fetch all people. I'd like to add a limit to to the number of friends each (Person) node will have (say e.g. max 5) when retrieved. Is this possible in graphQL? I know its possible to add a limit to allPeople, something like allPeople(limit: 5)
but i don't think that will help my use-case.
{
allPeople {
nodes {
id
friends {
name
id
phone
}
}
}
}
You can add params to friends 'level' in query
... if supported and resolved separately ...
... there is no filtering or searching syntax defined in general graphql specs.
It all depends on specific server/env, how resolved etc.
... probably it's better to resolve both levels (people+friends) in people resolver (one sql query) - in this case both filters/limits should be defined on 'parent' level - allPeople(limit:5, friendsLimit:5)

Spring Data Mongodb - findBy query with OR clause on same field

I'm working on mongo with spring data and using the query "findBy" based on property fields.
My goal will be find same value across multiple properties by OR clause like this:
List<Event> findByCreatorOrOrganizersOrGuests(User user);
this query involves 3 properties: "creator", "organizers" and "guests" that are a single value (creator) and 2 lists (organizers and guests) that contains the same class type (User)
at compile time I receive this error:
org.springframework.data.repository.query.ParameterOutOfBoundsException: Invalid parameter index! You seem to have declare too little query method parameters!
Do I need to repeat the same parameter 3 times? There's no workaround?
thanks
The using of Mongo queries for lists are not so efficient even if you define it with an index.
Another important thing is that the query:
List<Event> findByCreatorOrOrganizersOrGuests(User user);
includes some syntax errors (The MongoDB expects to get 3 parameters as variables int the ( ) relatively to the findBy keys, the return value should be inserted into a list object, and I am not sure that the Or in the find query is legal syntax.
As a concept the DB documents should have a good ability to be searched, cause it is the most expensive action.
When find using OR in MongoDB the direct query should looks like that:
def events = find({ $or: [ { user.username: { $lt: 20 } }, { price: 10 } ] } )
While searching in a list this is should be different, so please follow the links I attached.
When I try to think of the use you are looking for, I would suggest a different aspect. If the events is what interest you please read about the AbstractPersistenceEventListener. By define the appropriate
void onPostInsert(entity) {}
void onPostUpdate(entity) {}
void onPostDelete(entity) {}
You get all the events for each of the objects you want to listen to.
Here are 2 a great examples:
Example 1
Example 2

Resources