Skip to content

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

Merged

Conversation

Andy2003
Copy link
Collaborator

@Andy2003 Andy2003 commented Aug 5, 2020

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

resolves #3

@Andy2003 Andy2003 force-pushed the feature/GH3-nested-sorting-on-fields branch from 18a5595 to 9899853 Compare August 6, 2020 12:00
@@ -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)))
Copy link
Contributor

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.

Copy link
Collaborator Author

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

Copy link
Contributor

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?

Copy link
Collaborator Author

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
@Andy2003 Andy2003 force-pushed the feature/GH3-nested-sorting-on-fields branch from 9899853 to 891365c Compare August 7, 2020 14:19
@Andy2003
Copy link
Collaborator Author

fixes #115

@@ -206,7 +214,11 @@ open class ProjectionBase {
} ?: when {
isObjectField -> {
val patternComprehensions = if (fieldDefinition.isNeo4jType()) {
projectNeo4jObjectType(variable, field)
if (neo4jFieldsToPass.contains(fieldDefinition.innerName())) {
Copy link
Contributor

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})"
Copy link
Contributor

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?

Copy link
Collaborator Author

@Andy2003 Andy2003 Aug 31, 2020

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.

val deferredProjection = projectSelection("sortedElement", neo4jFiledSelection, nodeType, env, variableSuffix)
.map { cypher -> cypher.query }
.joinNonEmpty(", ")
comprehension = "[sortedElement IN $comprehension | sortedElement { .*, $deferredProjection }]"
Copy link
Contributor

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?

Copy link
Contributor

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?

Copy link
Collaborator Author

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

title
actors(orderBy:name_desc) {
name
movies(orderBy:[title_asc, title_desc]) {
Copy link
Contributor

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?

Copy link
Collaborator Author

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.

knows: [sortedElement IN apoc.coll.sortMulti([(userKnows)-[:KNOWS]->(userKnowsKnows:User) | userKnowsKnows {
.name,
born: userKnowsKnows.born
}], ['born','born']) | sortedElement {
Copy link
Contributor

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?

Copy link
Contributor

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?

Copy link
Collaborator Author

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 ] )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what was this again?

Copy link
Collaborator Author

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.

Copy link
Contributor

@jexp jexp left a 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
@jexp
Copy link
Contributor

jexp commented Aug 31, 2020

Also needs to be rebased.

@Andy2003 Andy2003 requested a review from jexp August 31, 2020 09:17
return arg?.value
?.let { it ->
when (it) {
is ArrayValue -> it.values.map { it.toJavaValue().toString() }
Copy link
Contributor

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?

Copy link
Collaborator Author

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" })
Copy link
Contributor

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

Copy link
Contributor

@jexp jexp left a 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.

@jexp jexp merged commit ba08a65 into neo4j-graphql:master Sep 2, 2020
@Andy2003 Andy2003 deleted the feature/GH3-nested-sorting-on-fields branch September 3, 2020 05:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

nested sorting also on fields
2 participants