I want to query a nested field for multiple variables.
In this case, I want to query RPR, but only return RPR if the label of the nested Region is given. One variable for the nested Region (field: label) works fine, but how can I filter on multiple variables of the same field?
The way I see it, when I call up the query-client (in my case through Apollo), I want to give an array as a variable and let the query in the backend go through that array and return results based on any of the variables given in the array.
The resolver does nothing more then:
rPRs: (root, args, ctx, info) => {
return ctx.db.query.rPRs(args, info);
}
The relevant part of the schema:
type RPR {
id: ID! #Unique
RPRID: String! #Unique
state: String
region: Region!
resource: Resource!
price: Float
theme: String
editionTitle: String
information: String
}
type Region {
id: ID! #Unique
regionID: String! #Unique
label: String! #Unique
name: String! #Unique
aov: Float!
aov_multiplier: Float!
}
The current query to retrieve all 'RPR' with nested regions:
query ADVICE_RESOURCES_QUERY($theme: String, $regio: String) {
rPRs(where: {
theme: $theme,
region: {
label: $regio
}
})
{
RPRID
region {
label
}
}
}
you should be able to use the label_in filter and provide the array of Strings to it. Your where would then look like this:
where: {
theme: $theme,
region: {
label_in: $regio
}
}
Related
I am currently following this workflow on the AWS Amplify docs:
https://docs.amplify.aws/lib/datastore/relational/q/platform/js/#many-to-many-relationships
Yet I cannot query my relational join tables. I am confused as to what I have done incorrectly in terms of syntax. This is my code and these are the errors I receive.
// schema.graph.ql
type Icd10 #model #auth(rules: [{allow: public}]) {
id: ID!
Code: String
Description: String
MedicalTests: [MedicalTest] #manyToMany(relationName: "Icd10MedicalTest")
Disease: [Disease] #manyToMany(relationName: "Icd10Disease")
}
type MedicalTest #model #auth(rules: [{allow: public}]) {
AdditionalIcd10: [String]
AdditionalTesting: String
ClinicalUtility: String
Cpt: [String]
DescriptiveMethodology: String
Icd10: [String]
Icd9: [String]
Interpretation: String
Loinc: [String]
Methodology: String
Name: String
Overview: String
PanelTests: [String]
ReferenceRanges: String
References: String
SpecimenCollection: String
SpecimenType: String
Synonyms: [String]
TurnaroundTime: String
createdAt: AWSDateTime!
id: ID!
updatedAt: AWSDateTime!
uuid: String
ratings: [Rating] #manyToMany(relationName: "RatingMedicalTest")
icd10s: [Icd10] #manyToMany(relationName: "Icd10MedicalTest")
}
// TransferData.js
const value = await DataStore.query(MedicalTest,
m => m.Name.eq("11-Dehydro-Thromboxane B2, Urine")
)
console.log(value)
const result = await DataStore.query(Icd10,
m => m.MedicalTests.MedicalTest.id.eq(value.id)
)
console.log("updateIcd10MedicalTest Successful!")
console.log(result)
Error Image
I have attempted to change the input values multiple times as I thought maybe I was wrong in reading how my schema functioned as I'm new to GraphQL.
I am wondering if it is possible to pass multiple IDs to a useQuery for apollo hook. Or run a single query per ID, and if so how would I go about doing so.
I have the following query
const DECOR_SHEET = gql`
query GetDecorSheet($id: ID!) {
findDecorSheetByID(id:$id){
refIdArray
sheetName
_id
}
}
`;
and the following useQuery hook
const { loading, error, data: sheetData } = useQuery(DECOR_SHEET, {
variables: { id: id },
context: {
headers: {
authorization: cookieBearer,
},
},
});
I have the following IDs 293164663883956749, 293526016787218952 and I would like to return into one object in order to render into a component.
I am using Fauna DB and this is the input graphQL schema
type Catalog {
decor: Boolean
clothing: Boolean
supplies: Boolean
furniture: Boolean
owner: User
}
type Decor {
description: String
pieces: Int
purchaser: String
alterations: Boolean
cost: Int
purchaseDate: Date
category: String
image: String
itemNum: Int
owner: User!
visible: Boolean
}
type DecorSheet {
sheetName: String
refIdArray: String
owner: User!
}
type User {
email: String! #unique
catalog: Catalog
decor: [Decor!] #relation
decorSheet: [DecorSheet!] #relation
}
and this is the generated schema
directive #embedded on OBJECT
directive #collection(name: String!) on OBJECT
directive #index(name: String!) on FIELD_DEFINITION
directive #resolver(
name: String
paginated: Boolean! = false
) on FIELD_DEFINITION
directive #relation(name: String) on FIELD_DEFINITION
directive #unique(index: String) on FIELD_DEFINITION
type Catalog {
_id: ID!
decor: Boolean
clothing: Boolean
supplies: Boolean
owner: User
furniture: Boolean
_ts: Long!
}
input CatalogInput {
decor: Boolean
clothing: Boolean
supplies: Boolean
furniture: Boolean
owner: CatalogOwnerRelation
}
input CatalogOwnerRelation {
create: UserInput
connect: ID
disconnect: Boolean
}
scalar Date
type Decor {
purchaseDate: Date
visible: Boolean
image: String
description: String
_id: ID!
alterations: Boolean
cost: Int
pieces: Int
category: String
owner: User!
purchaser: String
itemNum: Int
_ts: Long!
}
input DecorInput {
description: String
pieces: Int
purchaser: String
alterations: Boolean
cost: Int
purchaseDate: Date
category: String
image: String
itemNum: Int
owner: DecorOwnerRelation
visible: Boolean
}
input DecorOwnerRelation {
create: UserInput
connect: ID
}
type DecorPage {
data: [Decor]!
after: String
before: String
}
type DecorSheet {
refIdArray: String
_id: ID!
sheetName: String
owner: User!
_ts: Long!
}
input DecorSheetInput {
sheetName: String
refIdArray: String
owner: DecorSheetOwnerRelation
}
input DecorSheetOwnerRelation {
create: UserInput
connect: ID
}
type DecorSheetPage {
data: [DecorSheet]!
after: String
before: String
}
scalar Long
type Mutation {
updateUser(
id: ID!
data: UserInput!
): User
createUser(data: UserInput!): User!
createDecorSheet(data: DecorSheetInput!): DecorSheet!
createDecor(data: DecorInput!): Decor!
deleteCatalog(id: ID!): Catalog
updateCatalog(
id: ID!
data: CatalogInput!
): Catalog
updateDecor(
id: ID!
data: DecorInput!
): Decor
updateDecorSheet(
id: ID!
data: DecorSheetInput!
): DecorSheet
deleteDecor(id: ID!): Decor
deleteUser(id: ID!): User
createCatalog(data: CatalogInput!): Catalog!
deleteDecorSheet(id: ID!): DecorSheet
}
type Query {
findUserByID(id: ID!): User
findCatalogByID(id: ID!): Catalog
findDecorByID(id: ID!): Decor
findDecorSheetByID(id: ID!): DecorSheet
}
scalar Time
type User {
catalog: Catalog
email: String!
_id: ID!
decor(
_size: Int
_cursor: String
): DecorPage!
decorSheet(
_size: Int
_cursor: String
): DecorSheetPage!
_ts: Long!
}
input UserCatalogRelation {
create: CatalogInput
connect: ID
disconnect: Boolean
}
input UserDecorRelation {
create: [DecorInput]
connect: [ID]
disconnect: [ID]
}
input UserDecorSheetRelation {
create: [DecorSheetInput]
connect: [ID]
disconnect: [ID]
}
input UserInput {
email: String!
catalog: UserCatalogRelation
decor: UserDecorRelation
decorSheet: UserDecorSheetRelation
}
There is an option to query with Fauna's FQL which may have a way of querying multiple IDs I will have to look into that, but would prefer to do this in graphQL with apollo if possible.
Thanks ahead of time
Thanks to support from FaunaDB
The following query and UDF does the trick
Query
type Query {
getMultipleDecors(DecorId: [ID!]): [Decor]
#resolver(name: "get_multiple_decors")
}
udf named get_multiple_decors
Query(
Lambda(
["input"],
Let(
{
data: Map(
Var("input"),
Lambda("x", Get(Ref(Collection("Decor"), Var("x"))))
)
},
Var("data")
)
)
)
If it's always exactly two ids, you can fetch both objects in a single query easily using field aliases:
const DECOR_SHEET = gql`
query GetDecorSheet($firstId: ID!, $secondId: ID!) {
firstDecorSheet: findDecorSheetByID(id: $firstId) {
refIdArray
sheetName
_id
}
secondDecorSheet: findDecorSheetByID(id: $secondId) {
refIdArray
sheetName
_id
}
}
`;
I couldn't find any relevant info on Prisma docs, nor on SO on this question.
My relevant schema looks like this:
model User {
id Int #default(autoincrement()) #id
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
firstName String?
lastName String?
email String #unique
hashedPassword String?
role String #default("user")
sessions Session[]
profile Profile?
}
model Profile {
id Int #default(autoincrement()) #id
aboutMe String?
location String?
profession String?
user User #relation(fields:[userId], references: [id])
userId Int
}
I want to update multiple columns in both tables however, have been unable to get the mutation to work in Prisma. So, this is what my mutation looks like at the moment:
...
const {aboutMe, location, profession, firstName, lastName } = inputs;
const profile = await db.user.update({
where: { id: ctx.session!.userId },
data: {
profile: {
update: {
aboutMe,
location,
profession,
},
},
},
});
const user = await db.user.update({
where: { id: ctx.session!.userId },
data: {
firstName,
lastName,
},
});
...
As you can see, I have two mutations, is it possible the update multiple tables with a single mutation?
Thank you.
This should work:
const profile = await db.user.update({
where: { id: u.id },
data: {
firstName: 'name',
lastName: 'name',
profile: {
update: {
aboutMe: 'aboutMe',
location: 'aboutMe',
profession: 'aboutMe',
},
},
},
include: { profile: true },
})
What is the best way to keep order of nested objects in the schema.
My schema:
type Article {
id: ID! #id
pages: [Page!]!
}
type Page {
id: ID! #id
}
This is how I'm trying to sort the pages(unsuccessfully):
updateArticle({
variables: {
aricle.id,
data: {
pages: {
connect: reorderPages(aricle.pages)
}
}
}
The resolver:
t.field("updateArticle", {
type: "Article",
args: {
id: idArg(),
data: t.prismaType.updateArticle.args.data
},
resolve: (_, { id, data }) => {
return ctx.prisma.updateArticle({
where: { id },
data
});
}
});
I understand why this approach is wrong. I guess that the order should be written in the database by an order index in the connection table. I don't know how to process that by GraphQL/Nexus/Prisma/MySQL.
For N:M to relations the schema would look like this:
type Article {
id: ID! #id
title: String!
items: [ArticleItemEdge!]!
}
type ArticleItemEdge {
id: ID! #id
article: Article! #relation(link: INLINE)
item: Item! #relation(link: INLINE)
order: Int!
}
type Item {
id: ID! #id
title: String!
articles: [ArticleItemEdge!]!
}
And then query articles in a more "Relay" like fashion with edges & nodes
query {
articles {
items(orderBy: order_ASC) {
item {
title
}
}
}
}
And if N:M isn't needed, you can update the schema definition like so:
type Article {
id: ID! #id
items: [Item!]!
}
type Item {
id: ID! #id
article: Article! #relation(link: INLINE)
order: Int!
}
^ this will turn the db tables into 1:N relation ship rather than n:m
Then you can issue a query like so:
query {
articles {
id
items(orderBy: order_ASC) {
id
}
}
}
Updating the value of the "order" should be straight forward so I'll omit it here.
Hope it answers your question!
So I have the following in my Prisma datamodel. There's a relationship between the games and the characters, where the characters can appear in multiple games. Also the characters should be able to be listed on the games when the games alone are queried:
type Game {
id: ID! #unique
name: String! #unique
name_ja: String #unique
name_ko: String #unique
name_zh_CN: String #unique
name_zh_TW: String #unique
name_zh_HK: String #unique
characters: [Character]
filters: [GameFilter]
}
type Character {
id: ID! #unique
name: String! #unique
name_ja: String #unique
name_ko: String #unique
name_zh_CN: String #unique
name_zh_TW: String #unique
name_zh_HK: String #unique
games: [Game]
}
I then have this as a mutation for updating characters in my schema. I pass along an array of Game IDs because there's the possibility of multiple games being added within the same mutation:
updateCharacter(
name: String
name_ja: String
name_ko: String
name_zh_CN: String
name_zh_HK: String
name_zh_TW: String
id: ID!
games: [ID]
): Character!
And the following mutation written:
async updateCharacter(parent, args, ctx, info) {
if (!ctx.request.userId) {
throw new Error('You must be logged in');
}
const updates = {...args};
delete updates.id;
delete updates.games;
console.log(args.games);
const res = await ctx.db.mutation.updateCharacter({
data: updates,
games: {
connect: {
id: args.games
}
},
where: {
id: args.id
}
}, info);
return res;
}
And the following mutation written React-side. It's meant to pass along an array of IDs to the mutation (which will be expected because the schema assumes that an array of IDs will be passed along:
const UPDATE_CHARACTER_MUTATION = gql`
mutation UPDATE_CHARACTER_MUTATION(
$name: String!
$name_ja: String!
$name_ko: String!
$name_zh_CN: String!
$name_zh_TW: String!
$name_zh_HK: String!
$id: ID!
$games: [ID]!
) {
updateCharacter(
name: $name
name_ja: $name_ja
name_ko: $name_ko
name_zh_CN: $name_zh_CN
name_zh_TW: $name_zh_TW
name_zh_HK: $name_zh_HK
games: $games
id: $id
) {
id
name
name_ja
name_ko
name_zh_CN
name_zh_TW
name_zh_HK
games {
id
name
}
}
}
`;
I am also passing along the IDs of the games in an array onSubmit within the form to the mutation.
The result is that the mutation passes, but will only update the name fields, and the connection with the Games remains unchanged.
Not sure what I can do to make this mutate properly. I'm not sure whether passing the array directly into the mutation in the connect is what's causing the issue, but I tried mapping through and passing along each game id individually, but had the same result of the connection not updating.
The problem seems to be two-fold.
Regarding not seeing any changes at all:
In the mutation written, games is added to the async request json outside of data, meaning the data will never be found by the request.
Rather than:
data: ...,
games: ...
games must be part of data like such:
data: {
games: ...
}
Regarding wanting to do multiple connects:
GraphQL supports this style of nested updates using the following connect syntax:
connect: [
{ id : /* id from args */ },
{ id : /* another id from args */ },
...
]