Forum Discussion
Integrating Data from Microsoft Fabric's Lakehouse with Neo4j Graph Database
- 1 year ago
Hi syl-ade,
Thanks for your update. I'm glad you were able to create nodes successfully using your new approach. However, I see that your function writeNodesToNeo4j is still not working as expected.
- In your function, you are using "org.neo4j.spark" as the format. However, it should be "org.neo4j.spark.DataSource", like in your working version.
- Since your working approach included %%configure -f, ensure this configuration is present in the notebook before executing any Spark operations.
- Run the %%configure -f block before running the function.
- Try adding the following before calling writeNodesToNeo4j to ensure that Spark is recognizing the JAR correctly
Let me know if you still face issues! If this helps, please mark it as a solution and give a "Kudos" so other community members can find it easily.
Thank you.
Hi syl-ade,
Thanks for posting your query in Microsoft community forum.
The error message suggests that the Neo4j Spark Connector is not being properly recognized. Please try the following fixes:
- In your code, different cells are using different versions of the Neo4j Spark Connector:
Cell 1: 5.3.2_for_spark_3
Cell 2: 4.0.0_for_spark_3
Cell 5: 5.2.3_for_spark_3
To prevent conflicts, please update all your Spark session configurations to the latest stable version, 5.3.2_for_spark_3.
- Kindly update your write function to utilize "org.neo4j.spark" instead of "org.neo4j.spark.DataSource". Please also ensure that all dependencies are properly loaded before executing the write function.
If this helps, kindly Accept it as a solution and give a "Kudos" so other members can find it more easily.
Thank you.
The solution provided did not help t-wth the problem.
It started to create nodes with this code.
%%configure -f
{
"conf": {
"spark.jars": "abfss://[email protected]/Northwind_Lakehouse.Lakehouse/Files/Northwind/neo4j-spark-connector-5.3.1-s_2.12.jar"
}
}import org.apache.spark.sql.{SparkSession, SaveMode}
import org.apache.spark.sql.functions._
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.{DefaultScalaModule, ScalaObjectMapper}
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
// Set base path
val absfss_Base_Path = "abfss://[email protected]/Northwind_Lakehouse.Lakehouse/Files/Northwind/"
// Read Northwind data files
val customerDF = spark.read.option("header", true).csv(s"$absfss_Base_Path/customers.csv")
val supplierDF = spark.read.option("header", true).csv(s"$absfss_Base_Path/suppliers.csv")
val stagedOrderDF = spark.read.option("header", true).csv(s"$absfss_Base_Path/orders.csv")
.withColumn("addressID", concat_ws(", ", col("shipName"), col("shipAddress"), col("shipCity"), col("shipRegion"), col("shipPostalCode"), col("shipCountry")))
val orderDetailDF = spark.read.option("header", true).csv(s"$absfss_Base_Path/order-details.csv")
val productDF = spark.read.option("header", true).csv(s"$absfss_Base_Path/products.csv")
val categoryDF = spark.read.option("header", true).csv(s"$absfss_Base_Path/categories.csv")
// Create separate addressesDF and finalize orderDF
val addressDF = stagedOrderDF
.select($"addressID", $"shipName".alias("name"), $"shipAddress".alias("address"), $"shipCity".alias("city"), $"shipRegion".alias("region"), $"shipPostalCode".alias("postalCode"), $"shipCountry".alias("country"))
.dropDuplicates("addressID")
val orderDF = stagedOrderDF.drop("shipName", "shipAddress", "shipCity", "shipRegion", "shipPostalCode", "shipCountry")
// Load JSON file for Neo4j credentials
val jsonString = spark.read.text(s"$absfss_Base_Path/neo4j-conn.json").as[String].collect().mkString("\n")
// Parse JSON string
val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
val data = mapper.readValue[Map[String, Any]](jsonString)
// Extract Neo4j connection details
val neo4jUrl = data("NEO4J_URL").asInstanceOf[String]
val neo4jUsername = data("NEO4J_USERNAME").asInstanceOf[String]
val neo4jPassword = data("NEO4J_PASSWORD").asInstanceOf[String]
val neo4jOptions = Map(
"url" -> neo4jUrl,
"authentication.basic.username" -> neo4jUsername,
"authentication.basic.password" -> neo4jPassword
)
customerDF.write
.format("org.neo4j.spark.DataSource")
.mode(SaveMode.Overwrite)
.options(neo4jOptions)
.option("labels", "Customer")
.option("node.keys", "customerID")
.save()
supplierDF.write
.format("org.neo4j.spark.DataSource")
.mode(SaveMode.Overwrite)
.options(neo4jOptions)
.option("labels", "Supplier")
.option("node.keys", "supplierID")
.save()
stagedOrderDF.write
.format("org.neo4j.spark.DataSource")
.mode(SaveMode.Overwrite)
.options(neo4jOptions)
.option("labels", "Order")
.option("node.keys", "orderID")
.save()
Yet i still do not know how to run this part succesfully
// Write nodes to Neo4j
def writeNodesToNeo4j(dataFrame: DataFrame, label: String, nodeKey: String): Unit = {
dataFrame.write.format("org.neo4j.spark")
.mode(SaveMode.Overwrite)
.option("url", neo4jUrl)
.option("authentication.basic.username", neo4jUsername)
.option("authentication.basic.password", neo4jPassword)
.option("labels", label)
.option("node.keys", nodeKey)
.option("schema.optimization.node.keys", "KEY") //create node key constraints under the hood
.save()
}
writeNodesToNeo4j(customerDF, "Customer", "customerID")
writeNodesToNeo4j(supplierDF, "Supplier", "supplierID")
writeNodesToNeo4j(orderDF, "Order", "orderID")
writeNodesToNeo4j(productDF, "Product", "productID")
writeNodesToNeo4j(categoryDF, "Category", "categoryID")
writeNodesToNeo4j(addressDF, "Address", "addressID")- v-ssriganesh1 year ago
Community Support
Hi syl-ade,
Thanks for your update. I'm glad you were able to create nodes successfully using your new approach. However, I see that your function writeNodesToNeo4j is still not working as expected.
- In your function, you are using "org.neo4j.spark" as the format. However, it should be "org.neo4j.spark.DataSource", like in your working version.
- Since your working approach included %%configure -f, ensure this configuration is present in the notebook before executing any Spark operations.
- Run the %%configure -f block before running the function.
- Try adding the following before calling writeNodesToNeo4j to ensure that Spark is recognizing the JAR correctly
Let me know if you still face issues! If this helps, please mark it as a solution and give a "Kudos" so other community members can find it easily.
Thank you.- v-ssriganesh1 year ago
Community Support
Hi syl-ade,
I hope this information is helpful. Please let me know if you have any further questions or if you'd like to discuss this further. If this answers your question, please Accept it as a solution and give it a 'Kudos' so others can find it easily.
Thank you.