I’m currently learning how to evolve schemas.
At the beginning, I have a schema as follows:
type Post {
topic_title: String! @search(by:[fulltext]) # may be ""
topic_id: Int! # @id doesn't support Int for now
post_id: Int! # @id doesn't support Int for now
body: String! @search(by:[fulltext])
}
And a query as follows:
query Search($q: String!) {
queryPost(filter: {body: {anyoftext: $q}, or: { topic_title: {anyoftext: $q}}}) {
body
topic_title
topic_id
post_id
}
}
This is pretty straightforwards. Only one type, and one query that filters on both fields. There is obviously an external system (a postgres database) involved.
Now I want to evolve the schema to this:
type Post {
topic: Topic!
post_id: Int!
body: String! @search(by: [fulltext])
}
type Topic {
topic_id: Int!
title: String! @search(by:[fulltext])
}
This schema is what traditional database people would call a 1NF.
Observe now I cannot perform the same query. The following query would have a different semantics:
query Search($q: String!) {
queryPost(filter: {body: {anyoftext: $q}}) {
topic (filter: {title: {anyoftext: $q}}){
title
topic_id
}
post_id
body
}
}
Specifically, the semantics of the first query is that it filters with a OR
. But the semantics of the second query is that it filters first by the Post.body
THEN filter topics with the given keywords.
Instead I’d have to do something like this:
query MyQuery($q: String!) {
queryPost(filter: {body: {anyoftext: $q}}) {
post_id
body
topic {
title
topic_id
}
}
queryTopic(filter: {title: {anyoftext: $q}}) {
title
topic_id
}
}
This would then require me to do more work to extract first from queryPost
then from queryTopic
. This isn’t very ideal.
Question: is there a way to compress the results down into a similar structure as the first query? I seem to be missing something fundamental in my graphql education.