Skip to content

Commit

Permalink
Fixed #4066: Implement an apoc.convert.fromYaml function
Browse files Browse the repository at this point in the history
  • Loading branch information
gmarcostam authored and vga91 committed May 14, 2024
1 parent 7532119 commit 4239928
Show file tree
Hide file tree
Showing 10 changed files with 847 additions and 51 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
= apoc.convert.fromYaml
:description: This section contains reference documentation for the apoc.convert.fromYaml function.

label:function[] label:apoc-extended[]

[.emphasis]
apoc.convert.fromYaml(value, $config) - Deserializes the YAML string to Neo4j value

== Signature

[source]
----
apoc.convert.fromYaml(value :: STRING, config = {} :: MAP) :: ANY
----

== Input parameters
[.procedures, opts=header]
|===
| Name | Type | Default
|value|STRING|null
|config|MAP|{}
|===

== Config parameters
include::partial$usage/config/apoc.convert.fromYaml.adoc[]

[[yaml-dependencies]]
=== Install dependencies
Note that to use this function, you have to install additional dependencies
which can be downloaded https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/{apoc-release}/apoc-yaml-dependencies-{apoc-release}-all.jar[from this link].


[[usage-apoc.convert.fromYaml]]
== Usage Examples
include::partial$usage/apoc.convert.fromYaml.adoc[]


Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,9 @@

apoc.convert.toYaml(value, $config) - Serializes the given value to a YAML string
|label:function[]

|xref::overview/apoc.convert/apoc.convert.fromYaml.adoc[apoc.convert.fromYaml icon:book[]]

apoc.convert.fromYaml(value, $config) - Deserializes the YAML string to Neo4j value
|label:function[]
|===
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ apoc.config.map \| Lists the Neo4j configuration as map

apoc.convert.toYaml(value, $config) - Serializes the given value to a YAML string
|label:function[]

|xref::overview/apoc.convert/apoc.convert.fromYaml.adoc[apoc.convert.fromYaml icon:book[]]

apoc.convert.fromYaml(value, $config) - Deserializes the YAML string to Neo4j value
|label:function[]

|===

== xref::overview/apoc.couchbase/index.adoc[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ This file is generated by DocsTest, so don't change it!
*** xref::overview/apoc.config/apoc.config.map.adoc[]
** xref::overview/apoc.convert/index.adoc[]
*** xref::overview/apoc.convert/apoc.convert.toYaml.adoc[]
*** xref::overview/apoc.convert/apoc.convert.fromYaml.adoc[]
** xref::overview/apoc.coll/index.adoc[]
*** xref::overview/apoc.coll/apoc.coll.avgDuration.adoc[]
*** xref::overview/apoc.coll/apoc.coll.fillObject.adoc[]
Expand Down
309 changes: 309 additions & 0 deletions docs/asciidoc/modules/ROOT/partials/usage/apoc.convert.fromYaml.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,309 @@
We can convert any YAML string to list/map of nodes/rels

.Convert YAML string to map
[source,cypher]
----
RETURN apoc.convert.fromYaml("a: 42
b: foo") AS value
----

.Results
[opts="header",cols="1"]
|===
| value
a|
[source,json]
----
{
"b": "foo",
"a": 42
}
----
|===


.Convert YAML string to map, with custom mapping
[source,cypher]
----
RETURN apoc.convert.fromYaml("a: 42
b: foo", {mapping: {a: "Long"} }) AS value
----

.Results
[opts="header",cols="1"]
|===
| value
a|
[source,json]
{
"b": "foo",
"a": 42
}
|===

.Convert YAML string to map with custom features
[source,cypher]
----
RETURN apoc.convert.fromYaml("a: 42
b: foo", {enable: ['MINIMIZE_QUOTES'], disable: ['WRITE_DOC_START_MARKER']}) AS value
----

.Results
[opts="header",cols="1"]
|===
| value
a|
[source,json]
{
"b": "foo",
"a": 42
}
|===


.Convert YAML string to list
[source,cypher]
----
RETURN apoc.convert.fromYaml("---
- 1
- 2
- 3") as value
----

.Results
[opts="header",cols="1"]
|===
| value
a|
[source,json]
----
[1, 2, 3]
|===


.Convert YAML string to list and mapping type Long
[source,cypher]
----
RETURN apoc.convert.fromYaml("---
- 1
- 2
- 3",
{mapping: {_: "Long"}}) as value
----

.Results
[opts="header",cols="1"]
|===
| value
a|
[source,json]
----
[1, 2, 3]
|===

.Convert from YAML string to map
[source,cypher]
----
RETURN apoc.convert.fromYaml("---
a: 42
b: \"foo\"
c:
- 1
- 2
- 3") as value
----

.Results
[opts="header",cols="1"]
|===
| value
a|
[source,json]
----
{
"b": "foo",
"c": [
1,
2,
3
],
"a": 42
}
|===

.Convert from YAML string to node
[source,cypher]
----
RETURN apoc.convert.fromYaml("---
id: \"<elementID>\"
type: \"node\"
labels:
- \"Test\"
properties:
foo: 7") as value
----

.Results
[opts="header",cols="1"]
|===
| value
a|
[source,json]
----
{
"id": "<elementID>",
"labels": [
"Test"
],
"properties": {
"foo": 7
},
"type": "node"
}
|===

.Convert from YAML string to map with null values
[source,cypher]
----
RETURN apoc.convert.fromYaml("---
a: null
b: \"myString\"
c:
- 1
- \"2\"
- null") as value
----

.Results
[opts="header",cols="1"]
|===
| value
a|
[source,json]
----
{
"b": "myString",
"c": [
1,
"2",
null
],
"a": null
}
|===

.Convert from YAML string to map of nodes
[source,cypher]
----
RETURN apoc.convert.fromYaml("---
one:
id: \"8d3a6b87-39ad-4482-9ce7-5684fe79fc57\"
type: \"node\"
labels:
- \"Test\"
properties:
foo: 7
two:
id: \"3fc16aeb-629f-4181-97d2-a25b22b28b75\"
type: \"node\"
labels:
- \"Test\"
properties:
bar: 9
") as value
----

.Results
[opts="header",cols="1"]
|===
| value
a|
[source,json]
----
{
"two": {
"id": "3fc16aeb-629f-4181-97d2-a25b22b28b75",
"labels": [
"Test"
],
"properties": null,
"bar": 9,
"type": "node"
},
"one": {
"id": "8d3a6b87-39ad-4482-9ce7-5684fe79fc57",
"labels": [
"Test"
],
"foo": 7,
"properties": null,
"type": "node"
}
}
|===

.Convert from YAML string to relationship
[source,cypher]
----
RETURN apoc.convert.fromYaml("---
id: \"94996be1-7200-48c2-81e8-479f28bba84d\"
type: \"relationship\"
label: \"KNOWS\"
start:
id: \"8d3a6b87-39ad-4482-9ce7-5684fe79fc57\"
type: \"node\"
labels:
- \"User\"
properties:
name: \"Adam\"
end:
id: \"3fc16aeb-629f-4181-97d2-a25b22b28b75\"
type: \"node\"
labels:
- \"User\"
properties:
name: \"Jim\"
age: 42
properties:
bffSince: \"P5M1DT12H\"
since: 1993.1
") as value
----

.Results
[opts="header",cols="1"]
|===
| value
a|
[source,json]
----
{
"id": "94996be1-7200-48c2-81e8-479f28bba84d",
"start": {
"id": "8d3a6b87-39ad-4482-9ce7-5684fe79fc57",
"name": "Adam",
"labels": [
"User"
],
"properties": null,
"type": "node"
},
"label": "KNOWS",
"properties": {
"bffSince": "P5M1DT12H",
"since": 1993.1
},
"type": "relationship",
"end": {
"id": "3fc16aeb-629f-4181-97d2-a25b22b28b75",
"labels": [
"User"
],
"properties": {
"name": "Jim",
"age": 42
},
"type": "node"
}
}
|===
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
The procedure support the following config parameters:

.Config parameters
[opts=header, cols="1,1,1,5"]
|===
| name | type | default | description
| disable | list of strings | empty list | To disable one or more configurations, enabled by default, of the library used under the hood.
See https://www.javadoc.io/doc/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/latest/com/fasterxml/jackson/dataformat/yaml/YAMLGenerator.Feature.html[here].
| enable | list of strings | empty list | To enable one or more configurations of the library used under the hood.
See https://www.javadoc.io/doc/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/latest/com/fasterxml/jackson/dataformat/yaml/YAMLGenerator.Feature.html[here].
| mapping | map of strings | empty map | to map complex YAMLs.

In order to read complex types not supported by FasterXML Jackson, like Long...
we can use the mapping config to convert to the desired data type.
For example, if we have a YAML `a: 42 b: foo` , we can define a map `{mapping: {a: "Long"} }`

|===
Loading

0 comments on commit 4239928

Please sign in to comment.