Created
June 21, 2024 21:09
Revisions
-
dacr created this gist
Jun 21, 2024 .There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,106 @@ // summary : neo4j cypher queries - supported storable data types // keywords : scala, neo4j, cypher, @testable // publish : gist // authors : David Crosson // license : Apache NON-AI License Version 2.0 (https://raw.githubusercontent.com/non-ai-licenses/non-ai-licenses/main/NON-AI-APACHE2) // id : f7116c87-b923-401a-9d9a-dde815befd86 // created-on : 2024-06-20T08:29:22+02:00 // managed-by : https://github.com/dacr/code-examples-manager // run-with : scala-cli $file // --------------------- //> using scala "3.4.2" //> using dep "org.neo4j.test:neo4j-harness:5.20.0" //> using dep "org.neo4j.driver:neo4j-java-driver:5.21.0" // --------------------- import org.neo4j.driver.{AuthTokens, GraphDatabase, Result, Value} import scala.util.Using import scala.util.chaining.* import scala.jdk.CollectionConverters.* val fixture = """ |CREATE (:CoreType {name: 'INTEGER', example: 42}) // INTEGER IS Long 64bits |CREATE (:CoreType {name: 'FLOAT', example: 1.7976931348623157E308}) // FLOAT IS Double !! |CREATE (:CoreType {name: 'BOOLEAN', example: true}) |CREATE (:CoreType {name: 'STRING', example: 'hello'}) |CREATE (:CoreType {name: 'LIST', example: [1,2,3]}) |//CREATE (:CoreType {name: 'ByteArray', example: }) // NOT SUPPORTED IN CYPHER STANDARD |//CREATE (:CoreType {name: 'MAP', example: {age:42, name:"joe"}}) // NOT SUPPORTED & USELESS => GRAPH DB | |CREATE (:TemporalType {name: 'DATE', example: date('2024-06-20')}) |CREATE (:TemporalType {name: 'LOCAL TIME', example: time('10:02:32.192')}) |CREATE (:TemporalType {name: 'LOCAL DATETIME', example: datetime('2024-06-20T08:50:06')}) |CREATE (:TemporalType {name: 'ZONED DATETIME', example: datetime('2024-06-20T08:50:06+02:00')}) |CREATE (:TemporalType {name: 'ZONED TIME', example: time('10:02:32.192Z')}) |CREATE (:TemporalType {name: 'DURATION', example: duration('P14DT16H12M')}) | |CREATE (:SpatialType {name: 'POINT (2D Cartesian)', example: point({x: 2.3, y: 4.5}), srid: 7203}) |CREATE (:SpatialType {name: 'POINT (2D WGS-84)', example: point({latitude: 48.866667, longitude: 2.333333}) , srid: 4326}) |CREATE (:SpatialType {name: 'POINT (3D Cartesian)', example: point({x: 2.3, y: 4.5, z: 8.1}), srid: 9157}) |CREATE (:SpatialType {name: 'POINT (3D WGS-84)', example: point({latitude: 48.866667, longitude: 2.333333, height: 35.0}), srid: 4979}) |""".stripMargin val builder = org.neo4j.harness.Neo4jBuilders .newInProcessBuilder() .withFixture(fixture) Using(builder.build()) { embedded => Using(GraphDatabase.driver(embedded.boltURI(), AuthTokens.none())) { driver => Using(driver.session()) { session => // ------------------------------------------------ val byteArray = "Hello world".getBytes val createResponse = session.run("CREATE (:CoreType {name: 'ByteArray', example: $value})", Map( "value"-> byteArray ).asJava) // ------------------------------------------------ val readQuery = "MATCH (n {name: $name}) RETURN n.example as value" def get(name: String): Value = { val response: Result = session.run(readQuery, Map("name" -> name).asJava) val value: Value = response.single().get("value") value } def info(name: String, comment: Option[String] = None): Unit = { val value = get(name) println(s"---------------------") println(s"name:$name - type=${value.`type`().name()} - ${comment.getOrElse("")}") println(s"java class : ${value.getClass.getCanonicalName}") value.`type`().name() match case "BOOLEAN" => println(s"value:${value.asBoolean()}") case "LIST OF ANY?" => println(s"value:${value.asList().asScala.mkString(",")}") case "FLOAT" => println(s"value:${value.asDouble()}") case "INTEGER" => println(s"value:${value.asLong()}") case "STRING" => println(s"value:${value.asString()}") case "DATE" => println(s"value:${value.asLocalDate()}") case "DATE_TIME" => println(s"value:${value.asZonedDateTime()}") case "TIME" => println(s"value:${value.asOffsetTime()}") case "DURATION" => println(s"value:${value.asIsoDuration()}") case "POINT" => println(s"value:${value.asPoint()}") case "BYTES" => println(s"value:${value.asByteArray().mkString("-")}") case value => println(s"NOT YET SUPPORTED ${value.getClass.getCanonicalName}") } info("INTEGER", Some("is a Long value in fact (8 bytes)")) info("FLOAT", Some("is a Double value in fact (8 bytes)")) info("BOOLEAN") info("STRING") info("LIST") info("DATE") info("LOCAL TIME") info("LOCAL DATETIME") info("ZONED TIME") info("ZONED DATETIME") info("DURATION") info("POINT (2D Cartesian)") info("POINT (3D Cartesian)") info("POINT (2D WGS-84)") info("POINT (3D WGS-84)", Some("use height and not altitude")) info("ByteArray", Some("for small objects, not part of CYPHER standard")) // ------------------------------------------------ println("*****************************************************************") println("Constructed types cannot be stored as properties (with the exception of homogenous lists).") println("https://neo4j.com/docs/cypher-manual/current/values-and-types/property-structural-constructed/#constructed-types") println("*****************************************************************") }.tap(r => println(r)) }.tap(r => println(r)) }.tap(r => println(r))