Setup Japan Prefectures and Regions using neo4j and JavaScript

Setup Japan Prefectures and Regions using neo4j and JavaScript
作者: Calpa Liu
字數:6768
出版日期:August 19, 2022
更新日期:August 19, 2022

According to Wikipedia, Japan is divided into 47 `prefectures`(都道府県), and these prefectures are grouped into eight `regions` (八大地方區分).

According to Wikipedia, Japan is divided into 47 prefectures(都道府県), and these prefectures are grouped into eight regions (八大地方區分).

First, we get the prefectures and regions from jp-prefecture package.

const jpPrefecture = require("jp-prefecture");

const regions = jpPrefecture.getAll("region");

const prefectures = jpPrefecture.getAll("pref");

After that, we can peek the region data:

[{
  id: 1,
  name: "北海道",
  kana: "ホッカイドウ",
  en: "hokkaido",
  neighbor: [2]
},
{
  id: 2,
  name: "東北",
  kana: "トウホク",
  en: "tohoku",
  neighbor: [1]
}

It means that hokkaido region (id 1) has a neighbor tohoku region(id 2), so we can link them together using the neighbor relationship.

We may also peek the prefectures data:

[{
  id:1,
  region:1,
  name:"北海道",
  short:"北海道",
  kana:"ホッカイドウ",
  en:"hokkaido",
  neighbor:[2]
},
  {
  id:2,
  region:2,
  name:"青森県",
  short:"青森",
  kana:"アオモリ",
  en:"aomori",
  neighbor:[1, 3, 5]
}]

It means that hokkaido prefecture (id 1) has a neigbor amori (id: 2), and amori has three neigbor (id 1 hokkaido, 3 iwate, 5 akita).

Neo4j

We create a cypher to loop all the regions, set name, kana and en property to the region node, and link the region to its neighbor. So the cypher is look like:

UNWIND $regions as region
MERGE (r:Region{id: region.id})
SET r.name = region.name
SET r.kana = region.kana
SET r.en = region.en
WITH r, region.neighbor as neighbor
UNWIND neighbor as id
MERGE (r2:Region{id: id})
MERGE (r)-[:NEIGHBOR]-(r2)

Just like the region, we loop all the prefectures, set name, short, kana and en properties in the prefecture node. After creating the prefectures, we create a relationship from the prefecture to the region. Also we set the neighbor relationship for the prefectures. So the cypher looks like

UNWIND $prefectures as prefecture
MERGE (p:Prefecture{id: prefecture.id})
SET p.name = prefecture.name
SET p.short = prefecture.short
SET p.kana = prefecture.kana
SET p.en = prefecture.en

WITH p, prefecture.region as region, prefecture.neighbor as neighbor
MATCH (r:Region{id: region})
MERGE (p)-[:REGION]->(r)

WITH p, neighbor
UNWIND neighbor as id
MERGE (p2:Prefecture{id: id})
MERGE (p)-[:NEIGHBOR]-(p2)

Neo4j JavaScript Driver

Basically, we connect to the neo4j database using the neo4j package, create driver and create session. NEO4J_URI, NEO4j_USERNAME and NEO4J_PASSWORD are in the .env file or environment variable.

const neo4j = require('neo4j')
const driver = neo4j.driver(process.env.NEO4J_URI, neo4j.auth.basic(process.env.NEO4j_USERNAME, process.env.NEO4J_PASSWORD))

const session = driver.session()

You may also import and configure them using dotenv package:

require('dotenv').config()
NEO4J_URI=
NEO4j_USERNAME=
NEO4J_PASSWORD=

In order to query in the database, we write the cypher and insert the params.

const cypher = ``
const params = {}
await session.run(cypher, params)

So for writing the regions:

const cypher = `
UNWIND $regions as region
MERGE (r:Region{id: region.id})
SET r.name = region.name
SET r.kana = region.kana
SET r.en = region.en
WITH r, region.neighbor as neighbor
UNWIND neighbor as id
MERGE (r2:Region{id: id})
MERGE (r)-[:NEIGHBOR]-(r2)
`

await session.run(cypher, { regions })

And for writing the prefectures:

const cypher2 = `
UNWIND $prefectures as prefecture
MERGE (p:Prefecture{id: prefecture.id})
SET p.name = prefecture.name
SET p.short = prefecture.short
SET p.kana = prefecture.kana
SET p.en = prefecture.en

WITH p, prefecture.region as region, prefecture.neighbor as neighbor
MATCH (r:Region{id: region})
MERGE (p)-[:REGION]->(r)

WITH p, neighbor
UNWIND neighbor as id
MERGE (p2:Prefecture{id: id})
MERGE (p)-[:NEIGHBOR]-(p2)
`

await session.run(cypher2, { prefectures })

Don’t forget to close the session.

Putting things together

require('dotenv').config()

async function main () {
    const jpPrefecture = require("jp-prefecture");

    const regions = jpPrefecture.getAll("region");

    const prefectures = jpPrefecture.getAll("pref");

    const neo4j = require('neo4j-driver')
    const driver = neo4j.driver(process.env.NEO4J_URI, neo4j.auth.basic(process.env.NEO4j_USERNAME, process.env.NEO4J_PASSWORD))

    const session = driver.session()

    try {
        const cypher = `
        UNWIND $regions as region
        MERGE (r:Region{id: region.id})
        SET r.name = region.name
        SET r.kana = region.kana
        SET r.en = region.en
        WITH r, region.neighbor as neighbor
        UNWIND neighbor as id
        MERGE (r2:Region{id: id})
        MERGE (r)-[:NEIGHBOR]-(r2)
    `

        await session.run(cypher, { regions })

        const cypher2 = `
        UNWIND $prefectures as prefecture
        MERGE (p:Prefecture{id: prefecture.id})
        SET p.name = prefecture.name
        SET p.short = prefecture.short
        SET p.kana = prefecture.kana
        SET p.en = prefecture.en

        WITH p, prefecture.region as region, prefecture.neighbor as neighbor
        MATCH (r:Region{id: region})
        MERGE (p)-[:REGION]->(r)

        WITH p, neighbor
        UNWIND neighbor as id
        MERGE (p2:Prefecture{id: id})
        MERGE (p)-[:NEIGHBOR]-(p2)
    `

        await session.run(cypher2, { prefectures })
        console.log('Finished')
    } finally {
        session.close()
        console.log('Session is closed')
        process.exit(0)
    }
}

main()

Result

We now have all regions:

And we also have all prefectures:

We may also get the full picture of Japan using the following cypher query:

MATCH (p:Prefecture)-[:REGION]->(r:Region)
RETURN p, r

If I want to know the region of Kyoto (京都府) Prefecture, I can use the following cypher query:

MATCH (p:Prefecture{en: 'kyoto'})-[:REGION]->(r:Region)
RETURN p, r

So the answer is kinki (近畿).

Thoughts

I am really looking forward to travel to Japan one day, enjoying the Festival in Japan and playing maimai.

With neo4j, I can understand the relationship in Japan more easy.

btw, interesting thing that I find when I am writing this article.

Reference

  1. wadackel/jp-prefecture - Github
  2. motdotla/dotnev - Github
  3. List of regions of Japan - Wikipedia
  4. Prefectures of Japan - Wikipedia
感謝您閱讀我的文章。歡迎隨時分享你的想法。
關於 Calpa

Calpa 擅長使用 TypeScript、React.js 和 Vue.js 開發Responsive Web Design網站。

此外,Calpa 積極參與香港和台灣的開源社區,曾在2019年的香港開源大會上擔任講者,提供工作經驗和見解。此外,他也在 GitHub 上公開分享個人博客程式碼,已獲得超過300顆星星和60個分支的支持。

更多前端開發技術文章:傳送門