-
Notifications
You must be signed in to change notification settings - Fork 49
Nested sorting on fields #103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nested sorting on fields #103
Conversation
18a5595
to
9899853
Compare
@@ -34,7 +34,8 @@ class QueryHandler private constructor( | |||
.argument(input(OFFSET, Scalars.GraphQLInt)) | |||
.type(GraphQLNonNull(GraphQLList(GraphQLNonNull(GraphQLTypeReference(type.name))))) | |||
if (orderingTypeName != null) { | |||
builder.argument(input(ORDER_BY, GraphQLTypeReference(orderingTypeName))) | |||
val orderType = GraphQLList(GraphQLNonNull(GraphQLTypeReference(orderingTypeName))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
graphql automatically supports lists instead of single elements here for enums.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes but we should define the schema correctly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
won't that break single element sorts then? that already exist?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested it with GraphiQL and got no errors. And the tests are also green.
Can you point me to a doc describing the behavior you explained?
This commit add the following features: * sorting on multiple properties * sorting on fields * augmentation-tests provides a diff on failure that can be viewed in IntelliJ Bugfix: * The formatted field for temporal is now a string rather than an object
9899853
to
891365c
Compare
fixes #115 |
@@ -206,7 +214,11 @@ open class ProjectionBase { | |||
} ?: when { | |||
isObjectField -> { | |||
val patternComprehensions = if (fieldDefinition.isNeo4jType()) { | |||
projectNeo4jObjectType(variable, field) | |||
if (neo4jFieldsToPass.contains(fieldDefinition.innerName())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we give more of a semantic meaning to this expression?
@@ -230,7 +242,7 @@ open class ProjectionBase { | |||
.filterIsInstance<Field>() | |||
.map { | |||
val value = when (it.name) { | |||
NEO4j_FORMATTED_PROPERTY_KEY -> "$variable.${field.name}" | |||
NEO4j_FORMATTED_PROPERTY_KEY -> "toString($variable.${field.name})" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why did we have to do this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a Bug I discovered by comparing to the js-library. In case we should return the formatted
Date/DateTime/* property, this ensures, that a string will be returned instead the Date/DateTime/*-Object.
src/main/kotlin/org/neo4j/graphql/handler/projection/ProjectionBase.kt
Outdated
Show resolved
Hide resolved
val deferredProjection = projectSelection("sortedElement", neo4jFiledSelection, nodeType, env, variableSuffix) | ||
.map { cypher -> cypher.query } | ||
.joinNonEmpty(", ") | ||
comprehension = "[sortedElement IN $comprehension | sortedElement { .*, $deferredProjection }]" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we really want .*
? this can pull way too many properties that are not selected / asked for?
What do we need the deferredProjection for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are those sort fields that are not in the projection?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic I copied over form the js-library as well. The selection of the *. properties is done in the pattern comprehension so the sortedElement
will already be projected
src/test/resources/movie-tests.adoc
Outdated
title | ||
actors(orderBy:name_desc) { | ||
name | ||
movies(orderBy:[title_asc, title_desc]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should that be allowed to sort by the same property twice in two ways?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is taken over form the js-library. No it does not make any sense. I adjust it.
src/test/resources/movie-tests.adoc
Outdated
knows: [sortedElement IN apoc.coll.sortMulti([(userKnows)-[:KNOWS]->(userKnowsKnows:User) | userKnowsKnows { | ||
.name, | ||
born: userKnowsKnows.born | ||
}], ['born','born']) | sortedElement { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should one of these be ascending?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need to differentiate between nested levels?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean to have different names?
WITH createUser | ||
RETURN createUser { | ||
.userId, | ||
__typename: head( [ label IN labels(createUser) WHERE label IN $createUserValidTypes ] ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what was this again?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to have the name of the type when using interfaces, so that you know what concrete type the current entry is of.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, can you quickly check my comments, then we can merge it.
# Conflicts: # src/test/kotlin/org/neo4j/graphql/utils/GraphQLSchemaTestSuite.kt
Also needs to be rebased. |
return arg?.value | ||
?.let { it -> | ||
when (it) { | ||
is ArrayValue -> it.values.map { it.toJavaValue().toString() } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't we need to check here as well Enum/StringValue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it.toJavaValue()
does the check
if (values.isEmpty()) { | ||
return "" | ||
} | ||
return " ORDER BY " + values.joinToString(", ", transform = { (property, direction) -> "$variable.$property $direction" }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we might have to quote the property? if it has special characters/spaces? e.g. from an alias
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can check my comments for a later fix.
This commit add the following features:
Bugfix:
resolves #3