3

I have used jQAssistant to fill a Neo4j database with information about java artifacts.

Now I want to find the latest version of some artifact fulfilling some conditions. At first glance, I could use max(a.version) on the version property of an artifact. But artifact versions are not ordered by the usual String order, but actually 1.10.0 is a later version than 1.2.0.

How could I implement or use a custom ordering scheme like the one described above?

Dave Bennett
  • 10,996
  • 3
  • 30
  • 41
J Fabian Meier
  • 33,516
  • 10
  • 64
  • 142

2 Answers2

2

How about that for version numbers (major, minor and patch) to have their nodes? Something like that:

// Major
MERGE (M0:Semver:Major {v: 0}) 
MERGE (M1:Semver:Major {v: 1})
// Minor
MERGE (Mi0: Semver:Minor {v: 0 }) 
MERGE (Mi2: Semver:Minor {v: 2 }) 
MERGE (Mi10:Semver:Minor {v: 10})
// Patch
MERGE (P0:Semver:Patch {v:0}) 
MERGE (P2:Semver:Patch {v:2})

// Artifacts
MERGE (A1:Artifact {name:'Artifact 13afd'})
MERGE (A2:Artifact {name:'Artifact asdfk'})
MERGE (A3:Artifact {name:'Artifact 09sd2'})
MERGE (A4:Artifact {name:'Artifact skw30'})

// Versioning
MERGE (A1)-[:semver]->(M0) MERGE (A1)-[:semver]->(Mi0 ) MERGE (A1)-[:semver]->(P0)
MERGE (A2)-[:semver]->(M0) MERGE (A2)-[:semver]->(Mi0 ) MERGE (A2)-[:semver]->(P2)
MERGE (A3)-[:semver]->(M1) MERGE (A3)-[:semver]->(Mi2 ) MERGE (A3)-[:semver]->(P0)
MERGE (A4)-[:semver]->(M1) MERGE (A4)-[:semver]->(Mi10) MERGE (A4)-[:semver]->(P0)

RETURN *;

enter image description here

And the desired query:

MATCH  (A:Artifact)-[:semver]->(Mj:Semver:Major),
       (A         )-[:semver]->(Mi:Semver:Minor),
       (A         )-[:semver]->(Pt:Semver:Patch)
RETURN A.name,  Mj.v,     Mi.v,     Pt.v
       ORDER BY Mj.v asc, Mi.v asc, Pt.v asc
stdob--
  • 28,222
  • 5
  • 58
  • 73
0

You could break your version number string down into 3 separate attributes (major, minor, point) and keep each of those as an integer.

Consider the following data

create (n:Node {name: 'first',version: '1.2.0', ver_major: 1, ver_minor: 2, ver_point: 0})
create (n:Node {name: 'second',version: '1.10.0', ver_major: 1, ver_minor: 10, ver_point: 0})

As you have see if you search for and order by version they are returned in alphabetical order.

match (n:Node) 
return n.name, n.version 
order by n.version

One alternative would be to persist the version numbers in separate attributes as integers.

match (n:Node) 
return n.name, n.version 
order by n.ver_major, n.ver_minor, n.ver_point

Another alternative would be to split the string into component versions and order on those. toInt is required though otherwise the values will still be ordered as strings.

match (n:Node) 
return n.name
, n.version
, toInt(split(n.version,'.')[0]) as major
, toInt(split(n.version,'.')[1]) as minor
, toInt(split(n.version,'.')[2]) as point
order by major, minor, point
Dave Bennett
  • 10,996
  • 3
  • 30
  • 41