Skip to content
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

Inconsistency between apoc.coll.sort() and apoc.coll.sortNodes() #91

Closed
neo-technology-build-agent opened this issue Sep 1, 2022 · 1 comment

Comments

@neo-technology-build-agent
Copy link
Collaborator

Issue by ThachNgocTran
Thursday Jun 11, 2020 at 10:59 GMT
Originally opened as neo4j-contrib/neo4j-apoc-procedures#1554


Expected Behavior (Mandatory)

The documentation doesn't say anything about sorting order or special character (ASCENDING_ORDER_CHAR) at the beginning of property name to indicate sorting order (in case of sortNodes()). So users assume that the sorting is ascending (from smallest to largest). And if users want descending, they can additionally use apoc.coll.reverse().

Actual Behavior (Mandatory)

By default, sort() does ascending sorting. In contrast, sortNodes() does descending sorting. I think we should make their behavior consistent. Beside, reading the source code of sortNodes() (link), I found that there is a hidden trick of using "^" (ASCENDING_ORDER_CHAR defined in the code) to specify which sorting order to carry out. But this trick is not disclosed in the documentation for sortNodes(). It is in apoc.coll.sortMulti(); however, this is another section.

Steps (Mandatory)

For apoc.coll.sort(), in Neo4j Browser:

RETURN apoc.coll.sort([1,3,2,4,6,5])
# Return ascendingly ordered list.

For apoc.coll.sortNodes(), in Neo4j Browser:

CREATE (a:User {age: 20}), (b:User {age: 50}), (c:User {age: 30})
# then:
MATCH (n:User) RETURN apoc.coll.sortNodes(COLLECT(n), "age")
# Return descendingly ordered list.

Specifications (Mandatory)

Currently used versions

Versions

  • OS: Windows 8.1 x64 (JDK 11.0.7 x64).
  • Neo4j: Neo4j Desktop v4.0.4
  • Neo4j-Apoc: v4.0.0.12
@hvub
Copy link
Collaborator

hvub commented Dec 17, 2024

While it is true that it is consistent that the default sort order is ASC for one and DESC for the other, it is documented exactly like that:

(In other words, the document has probably been improved in the meantime.)

Changing the default, i.e. making apoc.coll.sortNodes sort ASC be default would be breaking change.

Further, making the default ASC require a notation of DESC. The notation for ASC is ^-prefix on the property name. There is no obvious alternative for DESC.

In general, regular Cypher should be used instead of these functions.

Any

...
WITH ..., apoc.coll.sort(list) AS sortedList
...

can be written as

...
CALL (list) {
  UNWIND list AS x
  WITH x ORDER BY x ASC // or DESC if the use case requires
  RETURN COLLECT(x) AS sortedList
}
...

or as

...
WITH ..., COLLECT {
  UNWIND list AS x
  RETURN x ORDER BY x ASC // or DESC if the use case requires
} AS sortedList
...

Any

...
WITH ..., apoc.coll.sortNodes(listOfNodes, 'prop') AS sortedListOfNodes
...

can be written as

...
CALL (listOfNodes) {
  UNWIND listOfNodes AS x
  WITH x ORDER BY x.prop DESC // or ASC in case of '^prop'
  RETURN COLLECT(x) AS sortedListOfNodes
}
...

or as

...
WITH ..., COLLECT {
  UNWIND listOfNodes AS x
  RETURN x ORDER BY x.prop DESC // or ASC in case of '^prop'
} AS sortedListOfNodes
...

@hvub hvub closed this as completed Dec 17, 2024
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

No branches or pull requests

2 participants