← Blog

June 6, 2026

Learning Neo4j with Okonomiyaki

Using a familiar food domain to learn graph modeling with shops, places, noren relationships, ingredients, and cooking steps.

Learning Neo4j with Okonomiyaki

Graph modeling is easier to understand when the domain is familiar.

Many graph database examples start with abstract data such as users, products, transactions, or social networks. These examples are useful, but they can feel distant for people who are new to graphs.

This article uses okonomiyaki as a small and familiar domain.

Okonomiyaki is a popular Japanese food, and Hiroshima has many well-known okonomiyaki shops. The topic is simple enough to enjoy, but it also has many useful relationships: shops, places, shop lineages, food categories, ingredients, sauces, and cooking steps.

The goal is not only to learn Cypher commands.

The goal is to see how ordinary knowledge can become a graph.

日本語補足:

この記事では、お好み焼きという身近な題材を使って、店舗、場所、のれん分け、材料、作り方をグラフとして表現します。目的はコマンドを試すことだけではなく、普通の知識がどのようにグラフになるかを見ることです。

Why okonomiyaki?

A good graph example should have relationships that people can understand without a long explanation.

Okonomiyaki works well for that.

A shop can be located in a place. A shop can have a noren relationship with another shop. A food can be a subtype of another food. A food can use ingredients and sauces. A cooking process can have steps that branch, merge, and continue.

These are simple ideas, but they are close to real graph modeling.

The same patterns appear in many business and technical domains:

  • locations and facilities
  • product categories
  • data lineage
  • system dependencies
  • business processes
  • recipes, procedures, and workflows
  • knowledge organization

That is why a small food example can be useful. It gives us a friendly way to talk about graph structure.

Loading shop data

The first step is to load okonomiyaki shop data from a CSV file.

The full CSV is available as a download. In this article, I show only a few rows so that the main focus stays on graph modeling rather than raw data.

Download okonomiyaki.csv

After downloading the CSV, place it under the Neo4j import directory as csv/okonomiyaki.csv.

日本語補足:

ダウンロードしたCSVは、Neo4j の import ディレクトリ配下に csv/okonomiyaki.csv として配置します。

A small part of the CSV looks like this:

"closed","name","kana","address","phone","open"
,"みっちゃん総本店 八丁堀本店",,"広島市中区八丁堀6-7 チュリス八丁堀1F","082-221-5438","11:30-14:30 / 17:30-21:00"
,"薬研堀 八昌","やげんぼりはっしょう","広島市中区薬研堀10-6","082-248-1776","11:00-22:00"
,"ロペズ",,"広島県広島市西区楠木町1-7-13","082-232-5277","16:30-23:00"

Each shop becomes a Shop node.

LOAD CSV WITH HEADERS FROM 'file:///csv/okonomiyaki.csv' AS line
INSERT (n:Shop {
  closed: trim(line.closed),
  name: trim(line.name),
  kana: trim(line.kana),
  address: trim(line.address),
  phone: trim(line.phone),
  open: trim(line.open)
});

The data includes shop names, addresses, phone numbers, opening hours, and closed dates when available.

For example, the dataset includes shops such as:

  • みっちゃん総本店 八丁堀本店
  • 五エ門 胡町本店
  • 電光石火 駅前ひろば店
  • 長田屋
  • 薬研堀 八昌
  • ロペズ
  • Masaru
  • やまさ家
  • お好み焼きテツジロウ

These are Japanese names, so the query examples also use Japanese text. That is not a problem. Neo4j can store and search Japanese strings as normal text.

Searching Japanese text

Once the shop nodes are loaded, we can search by name.

For example, to find shops whose names include お好み村:

MATCH (n:Shop)
WHERE n.name CONTAINS 'お好み村'
RETURN n;

We can also search by address.

MATCH (n:Shop)
WHERE n.address CONTAINS 'お好み村'
RETURN n;

This is a simple query, but it already shows an important point. Graph data does not have to start from a perfect model. We can begin with existing text data and then add structure step by step.

Adding a place

Next, we create a Place node for お好み村.

INSERT (n:Place {name: 'お好み村'});

Then we connect shops located in お好み村 to that place.

MATCH (s:Shop)
WHERE s.address CONTAINS 'お好み村'
MATCH (p:Place {name: 'お好み村'})
INSERT (s)-[:LOCATED_IN]->(p);

Now お好み村 is not just a string inside an address. It becomes a node in the graph.

This is a small but important modeling step. A place, category, person, product, or concept can start as text. Later, when it becomes important, we can promote it into a node and connect other data to it.

Modeling noren relationships

The next example is のれん.

In Japanese food culture, のれん分け often means that a shop or restaurant has a lineage or business relationship with another shop. It is not just a label. It is naturally relational.

That makes it a good graph example.

For example, we can connect 元祖八昌 to related shops.

MATCH (ganso:Shop {name: '元祖八昌'})
MATCH (yagen:Shop {name: '薬研堀 八昌'})
MATCH (lopez:Shop {name: 'ロペズ'})
INSERT (ganso)-[:NOREN]->(yagen)
INSERT (ganso)-[:NOREN]->(lopez);

We can also connect ロペズ to other shops.

MATCH (lopez:Shop {name: 'ロペズ'})
MATCH (noren:Shop)
WHERE noren.name IN ['Masaru', 'やまさ家', 'お好み焼きテツジロウ']
INSERT (lopez)-[:NOREN]->(noren);

Now we can ask relationship-based questions.

Which shops gave noren?

MATCH (n:Shop)-[:NOREN]->(:Shop)
RETURN n;

Which shops received noren?

MATCH (:Shop)-[:NOREN]->(n:Shop)
RETURN n;

Which shops received noren and then gave noren to another shop?

MATCH (:Shop)-[:NOREN]->(n:Shop)-[:NOREN]->(:Shop)
RETURN n;

Which shops received noren but did not give noren to another shop?

MATCH (:Shop)-[:NOREN]->(n:Shop)
WHERE NOT (n)-[:NOREN]->(:Shop)
RETURN n;

These queries are easy to read because the graph structure is close to the domain language.

日本語補足:

のれん分け は、親子関係、系譜、継承関係のように見ることができます。これはリレーショナルデータベースの表だけで見るより、グラフで表した方が自然です。

From shops to food knowledge

The workshop then moves from shops to food knowledge.

We create several Food nodes.

INSERT (:Food {name: 'お好み焼き'})
INSERT (:Food {name: 'たこ焼き'})
INSERT (:Food {name: 'うどん'})
INSERT (:Food {name: '中華麺'})
INSERT (:Food {name: '焼きそば'})
INSERT (:Food {name: 'もんじゃ焼き'});

Then we model types of okonomiyaki.

MATCH (okonomi:Food {name: 'お好み焼き'})
INSERT (:Food {name: '広島風お好み焼き'})-[:SUBTYPE_OF]->(okonomi)
INSERT (:Food {name: '関西風お好み焼き'})-[:SUBTYPE_OF]->(okonomi);

This gives us a small taxonomy.

  • 広島風お好み焼き is a subtype of お好み焼き
  • 関西風お好み焼き is a subtype of お好み焼き

This is a common graph pattern. We can use the same idea for products, documents, services, components, concepts, or business terms.

Modeling ingredients

Next, we connect food to ingredients.

For Hiroshima-style okonomiyaki:

MATCH (hiroshima:Food {name: '広島風お好み焼き'})
MATCH (udon:Food {name: 'うどん'})
MATCH (chuka:Food {name: '中華麺'})
INSERT (hiroshima)-[:USES_INGREDIENT]->(:Food {name: '小麦粉'})
INSERT (hiroshima)-[:USES_INGREDIENT]->(:Food {name: '卵'})
INSERT (hiroshima)-[:USES_INGREDIENT]->(:Food {name: 'キャベツ'})
INSERT (hiroshima)-[:USES_INGREDIENT]->(udon)
INSERT (hiroshima)-[:USES_INGREDIENT]->(chuka)
INSERT (hiroshima)-[:USES_INGREDIENT]->(:Sauce {name: 'オタフクソース'})
INSERT (hiroshima)-[:USES_INGREDIENT]->(:Sauce {name: 'カープソース'});

For Kansai-style okonomiyaki:

MATCH (kansai:Food {name: '関西風お好み焼き'})
MATCH (flour:Food {name: '小麦粉'})
MATCH (egg:Food {name: '卵'})
MATCH (cabbage:Food {name: 'キャベツ'})
INSERT (kansai)-[:USES_INGREDIENT]->(flour)
INSERT (kansai)-[:USES_INGREDIENT]->(egg)
INSERT (kansai)-[:USES_INGREDIENT]->(cabbage)
INSERT (kansai)-[:USES_INGREDIENT]->(:Sauce {name: 'イカリソース'})
INSERT (kansai)-[:USES_INGREDIENT]->(:Sauce {name: 'オリバーソース'});

Now we can ask questions such as:

Which food uses オタフクソース?

MATCH p=(:Sauce {name: 'オタフクソース'})--(:Food)
RETURN p;

Which food uses both オタフクソース and egg?

MATCH (:Sauce {name: 'オタフクソース'})--(n:Food)--(:Food {name: '卵'})
RETURN n;

This is a simple example of knowledge graph thinking. We are not only storing food names. We are connecting food, ingredients, sauces, and categories.

Modeling cooking steps

The final part models cooking steps.

For Hiroshima-style okonomiyaki, the process has parallel parts that are later combined.

MATCH (hiroshima:Food {name: '広島風お好み焼き'})
INSERT (hiroshima)-[:HAS_RECIPE]->(start:Step {name: 'START'})
INSERT (start)-[:NEXT]->(:Step {name: '生地'})-[:NEXT]->(:Step {name: '焼く'})-[:NEXT]->(mix:Step {name: '重ねて焼く'})
INSERT (start)-[:NEXT]->(:Step {name: 'キャベツ'})-[:NEXT]->(:Step {name: '焼く'})-[:NEXT]->(mix)
INSERT (mix)-[:NEXT]->(:Step {name: 'END'});

For Kansai-style okonomiyaki, the process is different.

MATCH (kansai:Food {name: '関西風お好み焼き'})
INSERT (kansai)-[:HAS_RECIPE]->(start2:Step {name: 'START'})
INSERT (start2)-[:NEXT]->(:Step {name: '生地'})-[:NEXT]->(mix2:Step {name: '混ぜる'})-[:NEXT]->(:Step {name: '焼く'})-[:NEXT]->(:Step {name: 'END'})
INSERT (start2)-[:NEXT]->(:Step {name: 'キャベツ'})-[:NEXT]->(mix2);

This is another important graph pattern. A process is not always a simple list. It can branch, merge, and continue.

That is useful not only for cooking, but also for:

  • business workflows
  • data pipelines
  • migration steps
  • manufacturing processes
  • approval flows
  • document review processes

Why this matters

This workshop is small, but it shows several important graph modeling ideas.

A shop can be connected to a place.

A shop can have a lineage relationship with another shop.

A food can be a subtype of another food.

A food can use ingredients.

A cooking process can be represented as connected steps.

These patterns are simple, but they are close to real business and technical data modeling.

Graph databases are not only for large-scale network analysis. They are also useful for explaining ordinary relationships clearly.

日本語補足:

お好み焼きという身近な題材でも、店舗、場所、のれん分け、材料、分類、作り方をグラフとして表現できます。小さなデータでも、関係性を明示すると検索や理解の仕方が変わります。

A note on relationship names

The original workshop used short relationship names for simplicity. In this blog version, I use slightly more descriptive names to make the graph model easier to understand.

For example:

  • PLACELOCATED_IN
  • IS_ASUBTYPE_OF
  • MADE_FROMUSES_INGREDIENT
  • HOW_TO_COOKHAS_RECIPE
  • STEPNEXT
  • NOREN remains NOREN

NOREN is kept as-is because it represents a Japanese cultural concept. In this article, NOREN is used as a simplified relationship for shop lineage or business inheritance.

日本語補足:

元のワークショップでは、コピペしやすい短いリレーション名を使っています。この記事ではBlogとして読みやすくするため、少し意味が分かりやすい名前に整理しています。NOREN は、のれん分け・系譜・店舗間の継承関係を表す簡略化したリレーションとして使います。

Workshop video

The original workshop was presented at OSC2024 Online/Fall.

You can follow the video and copy the original Cypher commands step by step.

Graph modeling becomes easier when the data is familiar.

For Japanese readers, okonomiyaki is familiar.

For international readers, it is also a good example of how local culture, food, shops, ingredients, and processes can become a small knowledge graph.