Skip to content

Commit 64765f2

Browse files
authored
feat: import exactly relationship.properties when specified (#791)
1 parent bf82dd7 commit 64765f2

File tree

7 files changed

+304
-64
lines changed

7 files changed

+304
-64
lines changed

common/src/main/scala/org/neo4j/spark/service/MappingService.scala

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,17 @@ class Neo4jWriteMappingStrategy(private val options: Neo4jOptions)
119119

120120
if (options.relationshipMetadata.relationshipKeys.contains(key)) {
121121
relMap.get(KEYS).put(options.relationshipMetadata.relationshipKeys.getOrElse(key, key), value)
122-
} else if (!source.includesProperty(key) && !target.includesProperty(key)) {
123-
relMap.get(PROPERTIES).put(options.relationshipMetadata.properties.getOrElse(key, key), value)
122+
} else {
123+
val propertyKey = options.relationshipMetadata.properties match {
124+
case Some(relProperties) => relProperties.get(key)
125+
case None =>
126+
if (!source.includesProperty(key) && !target.includesProperty(key)) {
127+
Some(key)
128+
} else {
129+
None
130+
}
131+
}
132+
propertyKey.foreach(k => relMap.get(PROPERTIES).put(k, value))
124133
}
125134
}
126135
}

common/src/main/scala/org/neo4j/spark/service/SchemaService.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -869,7 +869,7 @@ class SchemaService(
869869
.map(f => (f.name, f.name))
870870
.toMap
871871
val propsFromMeta: Map[String, String] =
872-
options.relationshipMetadata.relationshipKeys ++ options.relationshipMetadata.properties
872+
options.relationshipMetadata.relationshipKeys ++ options.relationshipMetadata.properties.getOrElse(Map.empty)
873873
createEntityTypeConstraint(
874874
"RELATIONSHIP",
875875
options.relationshipMetadata.relationshipType,

common/src/main/scala/org/neo4j/spark/util/Neo4jOptions.scala

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,12 @@ class Neo4jOptions(private val options: java.util.Map[String, String]) extends S
5757
}
5858

5959
private def getParameter(parameter: String, defaultValue: String = ""): String =
60-
Some(options.getOrDefault(parameter, defaultValue))
60+
getParameterOption(parameter).getOrElse(defaultValue)
61+
62+
private def getParameterOption(parameter: String): Option[String] =
63+
Some(options.get(parameter))
6164
.flatMap(Option(_)) // to turn null into None
6265
.map(_.trim)
63-
.getOrElse(defaultValue)
6466

6567
private def getAuthenticationParameters: Map[String, String] = {
6668
val authType = getParameter(AUTH_TYPE, DEFAULT_AUTH_TYPE)
@@ -176,26 +178,28 @@ class Neo4jOptions(private val options: java.util.Map[String, String]) extends S
176178

177179
val nodeMetadata: Neo4jNodeMetadata = initNeo4jNodeMetadata()
178180

179-
private def mapPropsString(str: String): Map[String, String] = str.split(",")
180-
.map(_.trim)
181-
.filter(_.nonEmpty)
182-
.map(s => {
183-
val keys = if (s.startsWith("`")) {
184-
val pattern = "`[^`]+`".r
185-
val groups = pattern findAllIn s
186-
groups
187-
.map(_.replaceAll("`", ""))
188-
.toArray
189-
} else {
190-
s.split(":")
191-
}
192-
if (keys.length == 2) {
193-
(keys(0), keys(1))
194-
} else {
195-
(keys(0), keys(0))
196-
}
197-
})
198-
.toMap
181+
private def mapPropsString(strOpt: Option[String]): Option[Map[String, String]] = strOpt.map(str =>
182+
str.split(",")
183+
.map(_.trim)
184+
.filter(_.nonEmpty)
185+
.map(s => {
186+
val keys = if (s.startsWith("`")) {
187+
val pattern = "`[^`]+`".r
188+
val groups = pattern findAllIn s
189+
groups
190+
.map(_.replaceAll("`", ""))
191+
.toArray
192+
} else {
193+
s.split(":")
194+
}
195+
if (keys.length == 2) {
196+
(keys(0), keys(1))
197+
} else {
198+
(keys(0), keys(0))
199+
}
200+
})
201+
.toMap
202+
)
199203

200204
private def initNeo4jNodeMetadata(
201205
nodeKeysString: String = getParameter(NODE_KEYS, ""),
@@ -204,8 +208,8 @@ class Neo4jOptions(private val options: java.util.Map[String, String]) extends S
204208
skipNullKeys: Boolean = getParameter(NODE_KEYS_SKIP_NULLS, "false").toBoolean
205209
): Neo4jNodeMetadata = {
206210

207-
val nodeKeys = mapPropsString(nodeKeysString)
208-
val nodeProps = mapPropsString(nodePropsString)
211+
val nodeKeys = mapPropsString(Some(nodeKeysString)).getOrElse(Map.empty[String, String])
212+
val nodeProps = mapPropsString(Some(nodePropsString)).getOrElse(Map.empty[String, String])
209213

210214
val labels = labelsString
211215
.split(":")
@@ -252,7 +256,7 @@ class Neo4jOptions(private val options: java.util.Map[String, String]) extends S
252256

253257
val nodeMap = getParameter(RELATIONSHIP_NODES_MAP, DEFAULT_RELATIONSHIP_NODES_MAP.toString).toBoolean
254258

255-
val relProps = mapPropsString(getParameter(RELATIONSHIP_PROPERTIES))
259+
val relProps = mapPropsString(getParameterOption(RELATIONSHIP_PROPERTIES))
256260

257261
val writeStrategy = RelationshipSaveStrategy.withCaseInsensitiveName(getParameter(
258262
RELATIONSHIP_SAVE_STRATEGY,
@@ -267,7 +271,7 @@ class Neo4jOptions(private val options: java.util.Map[String, String]) extends S
267271
DEFAULT_RELATIONSHIP_TARGET_SAVE_MODE.toString
268272
))
269273

270-
val relationshipKeys = mapPropsString(getParameter(RELATIONSHIP_KEYS, ""))
274+
val relationshipKeys = mapPropsString(getParameterOption(RELATIONSHIP_KEYS)).getOrElse(Map.empty)
271275

272276
Neo4jRelationshipMetadata(
273277
source,
@@ -389,7 +393,7 @@ case class Neo4jRelationshipMetadata(
389393
target: Neo4jNodeMetadata,
390394
sourceSaveMode: NodeSaveMode.Value,
391395
targetSaveMode: NodeSaveMode.Value,
392-
properties: Map[String, String],
396+
properties: Option[Map[String, String]],
393397
relationshipType: String,
394398
nodeMap: Boolean,
395399
saveStrategy: RelationshipSaveStrategy.Value,

common/src/main/scala/org/neo4j/spark/util/Validations.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ case class ValidateSchemaOptions(neo4jOptions: Neo4jOptions, schema: StructType)
4848
Neo4jOptions.NODE_KEYS -> schema.getMissingFields(neo4jOptions.nodeMetadata.nodeKeys.keySet),
4949
Neo4jOptions.NODE_PROPS -> schema.getMissingFields(neo4jOptions.nodeMetadata.properties.keySet),
5050
Neo4jOptions.RELATIONSHIP_PROPERTIES -> schema.getMissingFields(
51-
neo4jOptions.relationshipMetadata.properties.keySet
51+
neo4jOptions.relationshipMetadata.properties.getOrElse(Map.empty).keySet
5252
),
5353
Neo4jOptions.RELATIONSHIP_SOURCE_NODE_PROPS -> schema.getMissingFields(
5454
neo4jOptions.relationshipMetadata.source.properties.keySet

common/src/test/scala/org/neo4j/spark/util/Neo4jOptionsTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ class Neo4jOptionsTest {
204204

205205
val neo4jOptions: Neo4jOptions = new Neo4jOptions(options)
206206

207-
assertEquals(neo4jOptions.relationshipMetadata.properties, Map.empty)
207+
assertEquals(neo4jOptions.relationshipMetadata.properties, None)
208208
}
209209

210210
@Test

0 commit comments

Comments
 (0)