Introduction: From Data to Connections
Microsoft Fabric unifies data engineering, analytics, and AI across the Microsoft ecosystem.
But many business problems like fraud detection, customer 360, supply-chain optimization, … depend not on single data points, but on how those points connect.
Microsoft Fabric already gives organizations a strong foundation for analytics, governance, and AI across both structured and unstructured data.
But in the real world, not every challenge is about single rows in a table. Some of the toughest problems are about how things connect, the relationships that hide across systems, transactions, or interactions. That’s where a graph approach adds real power.
A few examples:
- Uncovering fraud: Fraudsters rarely act in isolation. They exploit networks of accounts, devices, and transactions. By following the links, a graph can reveal hidden loops or unusual clusters of activity that would be nearly impossible to spot in flat reports.
- Building a true Customer 360: Every customer leaves behind a trail of signals—an email in one system, a purchase in another, a loyalty card in a third. Graphs make it easy to stitch these fragments together into a single, connected view of the customer, enabling more accurate personalization and service.
- Delivering smarter recommendations: Whether it’s a movie, a product, or a service, recommendations work best when they reflect real connections: people who liked this also liked that or friends with similar tastes. Graphs capture these patterns naturally and make the reasoning behind suggestions transparent.
- Enhancing GenAI with context: Large language models are powerful, but they need grounding in reliable facts. A knowledge graph provides that context, ensuring GenAI answers are not just fluent but also accurate, explainable, and connected to enterprise truth.
Traditional SQL queries can express these patterns, but they become slow, complex, and hard to maintain. Graph databases are designed for this type of analysis.
With the new Neo4j Graph Workload for Microsoft Fabric, organizations can now explore complex relationships and patterns without ever leaving the Fabric environment.
What the Neo4j Graph Workload Brings to Fabric
The Neo4j Graph Workload runs natively in Fabric as a managed workload, powered by Neo4j AuraDB.
It lets you:
- Direct connection to Fabric Lakehouse data in OneLake, minimizing data movement.
- AI-assisted graph modeling, which automatically suggests nodes, relationships, and properties.
- Interactive graph exploration, enabling users to expand nodes and visually inspect relationships.
- Cypher query execution within Fabric’s query interface, to explore or for example create new relationships
- Access to 65+ Neo4j graph algorithms, including PageRank, Louvain, and node similarity.
- Connect to the AuraDB for further transformation via notebooks
- Visualize result in PowerBI through BI Connector for AuraDB (Simba Technologies)
- Microsoft Entra ID–based access control and integration with Fabric governance.
In short: it’s Fabric, but with relationship intelligence built in.
A complete, practical use case below walks you through each step of exploring these capabilities using a movie dataset in OneLake, so you can follow along and experience it yourself.
Current limitations (public preview)
Since this is a public preview, there are a few gaps to be aware of:
- One trial per tenant: only the first user can start the 14-day free AuraDB trial.
When one person in a Fabric tenant starts the free 14-day AuraDB Professional trial, that creates one shared Neo4j instance (tied to the Fabric workspace and region).
The trial is tenant-scoped: only the first user can trigger the creation of that instance.
However, once it’s created, up to 10 users can connect concurrently to the same Neo4j AuraDB graph workload through Fabric.
- Model customization: the GenAI-assisted graph modeling is automatic, but currently you cannot fully edit the graph schema before loading, although you can already change a lot.
- Writeback to OneLake: today, insights stay inside the AuraDB instance; writing them back into OneLake directly from the Graph interface is planned for a future release.
- No native connection for PowerBI ( no “Open in Power BI” button or Fabric credential flow or not supported by Fabric’s identity integration (Entra ID): it still uses the Aura-level credentials.
Despite these limitations, the integration is already functional and powerful enough for prototyping, proof-of-concepts, and early production scenarios.
What’s on the Roadmap
Microsoft and Neo4j have announced several upcoming enhancements that will further tighten integration and improve usability:
- Editable graph model designer, allowing users to fully modify node and relationship mappings before data load.
- Schema refresh and synchronization options for keeping the Explorer view up to date with changes in AuraDB. (seems already to be already OK as of Nov 2025)
- Write-back to OneLake, enabling seamless round-tripping of graph results to the Lakehouse for downstream analytics and Power BI.
- Enhanced Power BI integration, removing the need for the separate BI connector.
- Extended AI features, supporting more advanced GraphRAG and embeddings scenarios.
Pricing Model
While public preview documentation confirms a 14-day free trial of AuraDB Professional and shows a pay-as-you-go pricing model for AuraDB, the full cost model for the Graph Workload in Fabric, combining AuraDB subscription + Fabric capacity usage, is still being finalized by Microsoft and Neo4j. No clear documentation about this was found
Behind the Scenes: Building a Connected Movie Universe in Microsoft Fabric
To make the new Neo4j Graph Workload more tangible, we explored it with a simple but familiar dataset: movie data stored in OneLake.
This dataset contains tables for:
- Movies (title, release year, genre, …),
- Persons (actors, directors, producers)
- Users (people watching the movies)
- Roles (links between people and the movies they acted in, users rating movies and following other users (friends)).
In a traditional table-based view, these data sources are easy to query for facts: for example “Which movies did Tom Hanks play in?”
But the moment you start asking “Who tends to act together?”, “Which actor communities exist?”, or “Which movies can be recommended to certain users?”, relational joins become complex, inefficient, and difficult to reason about.
This is exactly where the graph approach shines.
Let’s explore step by step, You’ll see how to:
- Start in Fabric: Load movie-data into a Lakehouse.
Here, your data still lives in tables, the perfect starting point for structured analytics. - Turn it into a Graph: Use the Neo4j Graph Workload to automatically detect entities and relationships and transform tabular data into a graph model.
- Analyze and Enrich the Graph: Explore and analyze your graph using visual explorer and Cypher queries and use graph data science algorithms such as PageRank or Louvain to uncover communities, influencers or collaboration clusters and write back new insights.
- Operationalize it : Use Fabric notebooks to turn insights into action: for example, generate friend-based movie recommendations using the relationships in your graph, and write results back to your Lakehouse
- Visualize it : Bring your results to life in Power BI, either through direct connection to Neo4j AuraDB for real-time graph visuals or through your Lakehouse for governed analytics and dashboards.
Start in Fabric
Add the Neo4j Graph Workload
In your Fabric workspace:
- Click New → Neo4j Graph Workload.
- Choose a name for your workload and confirm the region (it must match your Fabric capacity region).
- Fabric will connect to Neo4j AuraDB and automatically create a 14-day free trial of AuraDB Professional tied to your tenant.
- The setup finishes in less than a minute, and from then on, you have a fully functional Neo4j graph database integrated directly into your Fabric environment.

Tips:
- If you’re deploying Neo4j in a new Fabric tenant, make sure an Azure SQL Server principal exists first. When we tried to enable the Neo4j Graph Workload in a newly created Fabric tenant, the setup failed with an “unauthorized” error. This happened because the tenant had no existing SQL Server principal, which Fabric relies on for secure authentication between Fabric and the managed AuraDB instance.
Creating a basic Azure SQL Server resource immediately resolved the issue
- Don’t forget to copy the password you get when creating the Neo4J instance, because you need it when connecting to the auraDB with notebook or PowerBI with default created user neo4j.

This instance is managed by Fabric but powered by Neo4j AuraDB — meaning you can query, visualize, and analyze your data without leaving Fabric.
Load and model movie data to lakehouse
We created some dummy movie data in csv’s. Downloadable at Github
This data we loaded into delta tables in a Lakehouse in our Workspace Demo

Turn it into a Graph
First create a new item ‘Neo4j Graph Dataset’ in the workspace where you added the Neo4j graphic workload.

Select the lakehouse you created with the moviedata, and select all the tables in there.

Using the GenAI-assisted graph modeling in the Fabric workload, the lakehouse tables gets transformed into a graph structure:

At this stage, the graph model has been generated, but the data has not yet been loaded into the AuraDB. You can still explore and refine the model before committing it.
If you click on a node or a relationship, the panel on the right shows which lakehouse table it is mapped to and which properties have been assigned.
This gives you a clear view of how your OneLake data will translate into a graph structure.

The interface allows you to extend the model before loading:
- To add a new node, hover over the edge of an existing node until a small plus (+) icon appears. Clicking it creates a new node in the diagram.
- To add a new relationship, drag the new node toward an existing one: a relationship line will appear automatically.
You can then define how this new node or relationship maps to your source data, ensuring that it connects to the correct tables and fields and that it represents a logical relationship within your data domain.
For example, you can add Country (a field of table movie and user) as a node and FILMED-IN, LIVED IN as new relationships like showed in below picture:

This editing step is useful if your data model evolves or if you want to include additional entities and relationships.
To load the data into graphDB click on ‘Transform to graph’

Analyze and Enrich the Graph
Exploring Your Graph Visually
The Explore tool, powered by Neo4j Bloom, lets you interact with your graph data visually, directly inside the Fabric environment.
Instead of writing queries, you can search for patterns, expand relationships, and style or filter nodes to uncover hidden connections.
Explore turns your data into an interactive network view, surfacing the relationships you already suspect exist, and revealing new ones you may never have noticed.
It’s an intuitive way to see context: how users, movies, and actors connect, cluster, or influence each other.
User manual of this functionality you find here

Querying Your Graph
You can also explore your data programmatically using Cypher, Neo4j’s powerful graph query language.
From the Query button in the Fabric ribbon, you can write, run, and visualize Cypher queries directly against your graph dataset.
The Query tool focuses on three key capabilities:
- Write and run Cypher queries to navigate, filter, and analyze your graph.
- View and write results back as new nodes or relationships
- Visualize query results that include graph entities such as nodes, relationships, or full paths.
When your query returns graph structures, Fabric automatically switches to the Graph View, showing an interactive network of connected nodes and relationships.
If your query only returns scalar values (like names, counts, or metrics), the tool will instead display the Raw or Table views for a clear, tabular result.
Example 1: Aggregated Query (Table View)
This query counts how many movies each actor has appeared in.
Because it returns only scalar values, it will be displayed in Table View:
MATCH (p:Person)-[:ACTS_IN]->(m:Movie)
RETURN p.name AS actor, count(m) AS movies
ORDER BY movies DESC
LIMIT 50;
What it shows:
A ranked list of the 50 most active actors, including how many movies each has appeared in.
Example 2: Relationship Query (Graph View)
This query finds actors who have co-starred with Sam Monroe and visualizes the collaboration network.
Because it returns both nodes and relationships, the results appear in Graph View
MATCH (a:Person {name: "Sam Monroe"})-[r1:ACTS_IN]->(m:Movie)<-[r2:ACTS_IN]-(co:Person)
RETURN a, r1, m, r2, co
LIMIT 50;
What it shows:
An interactive graph where Sam Monroe is connected to the movies they’ve acted in, and those movies link to all other actors who appeared alongside them.
The visualization highlights collaboration patterns: for instance, which actors frequently co-star with Sam Monroe or which films serve as bridges between different acting circles.

Using Graph Data Science on the Movies Graph
Once your movie data is in Neo4j, Graph Data Science (GDS) lets you go beyond exploration to measure influence, find communities, and surface similarity and write those insights back for searching, styling, and app logic.
What you can do with the movie data for example:
- Communities (Louvain / LPA): discover actor “ensembles” that frequently co-star (genre crews, recurring director teams).
- Influence (PageRank / Betweenness): find bridge actors who connect clusters (great for casting or promo targeting).
- Similarity (Node Similarity / Jaccard): suggest new collaborations (“people like you co-star with…”), or user–user/movie–movie lookalikes.
- Connectedness (WCC): identify isolated subgraphs (e.g., niche festivals or regional cinema pockets).
- Paths (k-hop queries): trace collaboration chains (“how is Actor A connected to Actor B?”).
We tried the Louvain algorithm
- in visual explorer
- in query tool :
– materialize a co-acting network in query tool
– run community detection
– write properties back to the graph for use in Explorer, Cypher, or downstream notebooks.
Explore Graph in visual explorer
Looking for communities of actors co-acting on a regular basis and give a different color to every community.

See usermanual
Materialize a Co-Acting Network in query tool
This query connects the dots between actors who have appeared in the same movie. It starts by finding every pair of people (p1, p2) who acted together in a movie (m).
To avoid duplicates (like creating both A→B and B→A), it keeps only one direction: the person with the lower internal ID points to the one with the higher ID.
For each pair of co-actors, it collects:
- movies: the list of movies they share,
- weight: how many times they’ve worked together,
- firstYear and last year: when they first and last appeared together.
Then it creates or updates a relationship (:Person)-[:CO_ACTED_WITH]->(:Person) between them and stores those details as properties.
The result is a direct actor-to-actor network you can analyze, style, and visualize. Instead of hopping through movies each time, you now have a compact graph that directly shows collaboration strength between actors.
// Create one directed edge per pair (deterministic: lower id -> higher id)
MATCH (m:Movie)<-[:ACTS_IN]-(p1:Person),
(m)<-[:ACTS_IN]-(p2:Person)
WHERE ElementId(p1) < ElementId(p2)
WITH p1, p2, collect(m) AS movies, count(*) AS weight,
min(m.year) AS firstYear, max(m.year) AS lastYear
MERGE (p1)-[r:CO_ACTED_WITH]->(p2)
SET r.weight = weight,
r.titles = [m IN movies | m.title],
r.firstYear = firstYear,
r.lastYear = lastYear;
Project the Graph to GDS and Run Algorithms
Project the Person layer with CO_ACTED_WITH as an undirected relationship and a weight property.
CALL gds.graph.drop('coacting', false); // ignore if it doesn't exist
CALL gds.graph.project(
'coacting',
'Person',
{
CO_ACTED_WITH: {
orientation: 'UNDIRECTED',
properties: 'weight'
}
}
);
Community detection (Louvain) : write back to nodes
CALL gds.louvain.write(
'coacting',
{
relationshipWeightProperty: 'weight',
writeProperty: 'communityId'
}
)
YIELD communityCount, modularity, modularities;
Now every (:Person) has a communityId, which you can use to color nodes in the visual Explorer or filter in Cypher/Power BI.
Visualize and Query the Results
With communityId and (optionally) pagerank written, you can immediately style and filter in Explore (Bloom in Fabric):
- Color by communityId to reveal ensembles.
Operationalize it : Further use of GraphData by notebooks
A natural next step after running your graph algorithms is to turn those insights into data you can act on.
Take the example of movie recommendations. Using the social graph (User)-[:FOLLOWS]->(User)-[:RATES]->(Movie), you can compute which movies a user’s trusted friends rate highly and generate a list of suggested titles they haven’t seen yet.
Inside Neo4j, those results could be represented as new relationships: for instance, (u)-[:RECOMMENDED]->(m) or stored as node properties. This is great for exploratory graph analytics, where you want to keep the full connectivity context visible and keep refining your algorithms.
However, once the recommendations are ready for broader consumption, it’s often more practical to write them back to Fabric Lakehouse:
- In Fabric, you can easily join recommendations with other datasets (e.g., user profiles, watch history, marketing segments).
- Data engineers can feed the results into pipelines, surfacing them to BI reports, dashboards, or personalization APIs.
- You can version, govern, and share the derived data alongside other enterprise data assets.
In short, the graph gives you discovery, understanding patterns that are hard to express in SQL, while the Lakehouse gives you the ability to operationalize and reuse those insights across analytics, ML, and applications.
For example, after generating friend-based movie recommendations in Neo4j, you might export the top 5 titles per user to a Delta table in your Lakehouse. Power BI can then visualize them as “Recommended for You” dashboards, or Synapse ML can train a ranking model on top.
The Friends-Based Recommendation Notebook
To operationalize this logic, we built a Fabric notebook that computes Top 5 friend-based movie recommendations per user and writes them as a structured table.
- Connect to Neo4j AuraDB
The notebook uses the official Neo4j Python driver to connect securely to your Aura instance. Use the password that you got when adding the Neo4J Graph workload. - Execute the Cypher logic
For each user, it:- Finds friends and their rated movies.
- Excludes movies the user has already rated.
- Calculates the average friend rating and vote count.
- Returns the top 5 movies per user.
- Transform with Pandas
The results are collected into a DataFrame, ranked per user, and enriched with a rank column. - Write to Delta / Lakehouse
Finally, the notebook saves the dataset to
Tables/neo4j_movies_recs_friends, either as a Delta table (in Fabric) or a Parquet file (if Spark isn’t available): - write_delta(recs, “neo4j_movies_recs_friends”)
# Welcome to your new notebook
# Type here in the cell editor to add code!
# =============================
# Friends-based recommendations (RATES / ACTS-IN)
# Writes: Tables/neo4j_movies_recs_friends
# =============================
%pip install --quiet neo4j~=5.28.0 pandas~=2.2.2
from neo4j import GraphDatabase
import pandas as pd
# ---- AuraDB config ----
AURA_URI = "neo4j+s://.databases.neo4j.io"
AURA_USER = "neo4j"
AURA_PASSWORD = ""
WRITE_MODE = "overwrite" # or "append"
# If your data model uses different labels/properties, adjust here:
# Model-specific names (adjust if needed)
USER_LABEL = "User"
MOVIE_LABEL = "Movie"
FOLLOWS_REL = "FOLLOWS"
RATES_REL = "RATES" # per your graph
RATING_PROPERTY = "rating" # property on RATES
TOP_N_PER_USER = 5
def run_df(query: str, params: dict | None = None) -> pd.DataFrame:
with GraphDatabase.driver(AURA_URI, auth=(AURA_USER, AURA_PASSWORD)) as driver:
with driver.session() as session:
return pd.DataFrame(session.run(query, params or {}).data())
def write_delta(df: pd.DataFrame, table_path: str, mode: str = "overwrite"):
if df is None or df.empty:
print(f"[WARN] No data for {table_path}; nothing written.")
return
try:
spark # Fabric Spark available?
sdf = spark.createDataFrame(df)
sdf.write.format("delta").mode(mode).save(f"Tables/{table_path}")
print(f"[OK] Wrote Delta: Tables/{table_path} (rows: {len(df)})")
except NameError:
fp = f"/mnt/data/{table_path}.parquet"
df.to_parquet(fp, index=False)
print(f"[OK] No Spark; wrote Parquet: {fp} (rows: {len(df)})")
# Connectivity (optional)
ver = run_df("CALL dbms.components() YIELD name, versions RETURN versions[0] AS version")
print(f"[OK] Connected to Neo4j {ver.iloc[0]['version'] if not ver.empty else 'unknown'}")
# ---- Cypher: variable-scoped subquery without returning `u` ----
cypher = f"""
MATCH (u:{USER_LABEL})
CALL (u) {{
WITH u
MATCH (u)-[:{FOLLOWS_REL}]->(f:{USER_LABEL})-[r:{RATES_REL}]->(m:{MOVIE_LABEL})
WHERE NOT (u)-[:{RATES_REL}]->(m)
WITH m,
avg(coalesce(r.{RATING_PROPERTY}, 0.0)) AS score,
count(*) AS votes
ORDER BY score DESC, votes DESC, m.title ASC
LIMIT $top
RETURN m.title AS movie, score, votes
}}
RETURN u.name AS user, movie, score, votes
ORDER BY user ASC, score DESC, votes DESC, movie ASC
"""
recs = run_df(cypher, {"top": TOP_N_PER_USER})
# Rank per user (1..TOP_N_PER_USER)
if not recs.empty:
recs["rank"] = recs.groupby("user", sort=False).cumcount() + 1
write_delta(recs, "neo4j_movies_recs_friends")
Visualizing Graph Insights in Power BI
Power BI can connect straight to Neo4j AuraDB using the Neo4j BI Connector (ODBC/JDBC).
This connector translates Cypher query results into a virtual SQL layer, allowing Power BI to query graph data as if it were relational, while keeping the speed and flexibility of graph traversal.
Install the Neo4j BI Connector from the Neo4j Download Center
The authentication is done with the default user neo4j and the password that you copied when you first created a Neo4j graphDB

Instantly build dashboards from graph views, such as actor–movie networks, influencer rankings, or similarity clusters.
This setup bypasses the Fabric Graph Workload UI for now, connecting directly to the AuraDB instance behind it.
It’s stable, production-ready, and ideal when you want interactive Power BI dashboards on graph data.
ABOUT THE AUTHOR
An De Lafonteyne
Managing Partner BE-Flanders




