# LAPORAN AKHIR PROOF OF CONCEPT (PoC) TASK 2: GDS PAGERANK VISUAL NODE SIZING

**Status:** Selesai dan Diverifikasi  
**Tanggal Laporan:** 27 April 2026

---

## 1. JUDUL DAN IDENTITAS PROYEK

**Judul Proyek:** Proof of Concept Task 2 - GDS PageRank Visual Node Sizing untuk Neo4j Vector Knowledge Graph
**Identitas Teknis:** PoC Task 2 GDS PageRank Pipeline  
**Versi Aktif:** GDS_PageRank_Implementation_Plan  
**Status:** Completed dan Production-Ready (Limited Scope)

---

## 2. DESKRIPSI PROOF OF CONCEPT

Proof of Concept (PoC) ini merupakan kelanjutan dari PoC ekstraksi dan ingestion knowledge graph (redesign_2). Setelah node dan relasi semantik berhasil dibangun di Neo4j, tantangan berikutnya adalah bagaimana merepresentasikan visualisasi graf tersebut agar intuitif bagi pengguna. Jika semua node ditampilkan dengan ukuran yang sama, pengguna akan kesulitan membedakan mana literatur yang menjadi pusat penelitian utama (hub) dan mana yang hanya merupakan literatur pendukung (leaf).

Oleh karena itu, PoC ini mengimplementasikan algoritma **PageRank** menggunakan library **Neo4j Graph Data Science (GDS)**. PageRank akan menghitung nilai sentralitas (pengaruh) dari setiap node literatur berdasarkan jumlah dan bobot (score similarity) dari relasi yang terhubung kepadanya. Nilai PageRank mentah (`pagerank_raw`) ini kemudian dinormalisasi menggunakan metode Min-Max Scaling ke dalam rentang nilai visual yang telah ditentukan (10.0 - 50.0). Hasil akhir disimpan dalam properti `visual_pagerank_size` pada setiap node, yang nantinya akan langsung dikonsumsi oleh library frontend seperti Vis.js untuk menentukan ukuran radius node saat dirender.

Proses ini berjalan sebagai pipeline post-processing yang independen, dijalankan setelah proses ingestion selesai, dan dirancang untuk efisien memori (ramah untuk AuraDB Free Tier) melalui pendekatan "project, write, drop".

---

## 3. ARSITEKTUR PROOF OF CONCEPT

Arsitektur PoC ini berbentuk pipeline data processing linear yang berjalan dalam satu skrip Python (`calculate_pagerank.py`). Skrip ini berkomunikasi dengan instance Neo4j (Self-Hosted/AuraDB) melalui protokol Bolt/Neo4j.

Berbeda dengan proses ingestion yang menggunakan arsitektur multi-threading asynchronous, kalkulasi PageRank ini didesain sepenuhnya **sinkron dan transaksional**. Keputusan ini diambil karena operasi graf (seperti PageRank) harus melihat *state* graf secara keseluruhan pada satu waktu (global analytics), sehingga paralelisasi di tingkat client tidak relevan. Perhitungan paralel dilakukan secara internal oleh engine Neo4j GDS di sisi server.

Pipeline ini terbagi menjadi empat fase utama:
1. **Setup & Preflight:** Memverifikasi koneksi ke Neo4j dan memastikan bahwa graf tidak kosong. Jika jumlah node atau relasi `SIMILAR_*` adalah nol, pipeline akan berhenti secara graceful untuk mencegah error pada GDS.
2. **GDS Core (Ephemeral Named Projection):** Fase utama di mana data graf dimuat ke memori (projected graph). Algoritma PageRank dijalankan dengan mempertimbangkan bobot relasi (`score`). Hasil komputasi (`pagerank_raw`) ditulis kembali ke database, lalu graf di memori segera dihapus untuk membebaskan RAM.
3. **Normalization (Server-side Math):** Menggunakan query Cypher untuk mengekstrak nilai minimum dan maksimum dari `pagerank_raw`. Kemudian, perhitungan rumus Min-Max Scaling dilakukan langsung di sisi database menggunakan fungsi agregasi dan operasi matematika Cypher. Properti sampah hasil intermediate kemudian dihapus.
4. **Reporting:** Mengambil hasil normalisasi dan metrik eksekusi, lalu menampilkannya sebagai laporan audit terstruktur di console terminal.

---

## 4. TEKNOLOGI, ASUMSI, DAN SPESIFIKASI

**Stack Teknologi:**
- **Bahasa:** Python 3.10+
- **Driver Database:** `neo4j` (Official Python Driver)
- **Database:** Neo4j Community Edition (Self-Hosted) atau Neo4j AuraDB (Cloud)
- **Plugin Database:** Neo4j Graph Data Science (GDS) v2.13.x+

**Asumsi-Asumsi Kunci:**
1. **Neo4j GDS Terinstal:** Instance Neo4j harus memiliki plugin GDS yang diaktifkan. Skrip tidak menginstal GDS, hanya memanggil prosedurnya.
2. **Data Telah Ter-Ingest:** Pipeline ini mengasumsikan skrip `orchestrator_ingest.py` telah selesai dijalankan. Harus ada node dengan label `Literature` dan relasi dengan awalan `SIMILAR_` (seperti `SIMILAR_BACKGROUND`, dsb) yang memiliki properti `score`.
3. **Rentang Visual:** Ditetapkan bahwa ukuran visual terkecil untuk node adalah 10.0 dan terbesar adalah 50.0. Rentang ini dianggap ideal untuk perenderan oleh Vis.js tanpa menyebabkan node terlihat terlalu kecil (menghilang) atau terlalu besar (menutupi node lain).

**Spesifikasi Constraint:**
- **Memory Efficiency:** Dibatasi agar tidak memicu OOM (Out of Memory) pada environment terbatas seperti AuraDB Free Tier.
- **Idempotency:** Skrip aman dijalankan berulang kali. Eksekusi ulang akan menimpa nilai `visual_pagerank_size` sebelumnya.
- **Zero-Division Guard:** Jika graf sangat homogen (semua node memiliki PageRank yang identik), proses scaling harus dilindungi dari pembagian dengan nol.

---

## 5. PENJELASAN CARA KERJA ARSITEKTUR PROOF OF CONCEPT

Eksekusi dimulai ketika pengguna menjalankan perintah `python calculate_pagerank.py`.

**Fase 1: Setup & Preflight Check (PR-01)**
Skrip membaca kredensial dari file `.env` dan membuka koneksi ke Neo4j. Sebelum memicu GDS, skrip menjalankan query agregasi sederhana (`MATCH (n:Literature) RETURN count(n)`) untuk memastikan node tersedia. Hal yang sama dilakukan untuk relasi (`MATCH ()-[r]->() WHERE type(r) STARTS WITH 'SIMILAR_' RETURN count(r)`). Jika keduanya valid (>0), pipeline berlanjut.

**Fase 2: GDS Core (PR-02)**
Skrip mengeksekusi tiga langkah GDS. Pertama, ia memproyeksikan graf dari disk ke in-memory catalog menggunakan `gds.graph.project`. Node yang diambil adalah `Literature` dan relasinya adalah semua tipe (menggunakan wildcard `['*']` karena properti relationshipProjection tidak mendukung wildcard di beberapa versi GDS, pendekatan Cypher-based projection digunakan jika perlu, namun untuk GDS 2.13.9, native projection dengan array type berhasil digunakan secara stabil). Properti `score` dari relasi dimuat sebagai beban bobot (weight).
Kedua, `gds.pageRank.write` dipanggil terhadap graf in-memory tersebut. Algoritma diset untuk mempertimbangkan `relationshipWeightProperty: 'score'`. Hasil kalkulasi ditulis ke node di database dengan nama properti `pagerank_raw`.
Ketiga, setelah data tersimpan, memori dikembalikan ke sistem dengan menjalankan `gds.graph.drop`.

**Fase 3a: Min-Max Extraction (PR-03)**
Untuk menormalisasi data, kita perlu mengetahui rentang sebaran. Skrip menjalankan query Cypher: `MATCH (n:Literature) WHERE n.pagerank_raw IS NOT NULL RETURN min(n.pagerank_raw), max(n.pagerank_raw)`. Nilai absolut terkecil dan terbesar ini ditarik ke dalam variabel Python.

**Fase 3b: Scaling Math & Zero Guard (PR-04)**
Skrip mengirimkan nilai min dan max kembali ke Neo4j bersama dengan variabel target (`VISUAL_SIZE_MIN` = 10, `VISUAL_SIZE_MAX` = 50). Kalkulasi Min-Max Scaling dieksekusi secara native oleh Neo4j terhadap seluruh node secara bersamaan melalui perintah `SET`. Query Cypher menyertakan logika `CASE WHEN $raw_max = $raw_min THEN ... ELSE ... END` untuk mencegah error *Division by Zero*. Jika semua node bernilai sama, mereka semua diberikan ukuran median (30.0). Hasil komputasi akhir disimpan sebagai `visual_pagerank_size`.

**Fase 3c: Cleanup Property (PR-05)**
Karena `pagerank_raw` hanya berupa data sementara (intermediate data) yang tidak relevan untuk frontend, properti tersebut dihapus dari skema menggunakan perintah `REMOVE n.pagerank_raw`. Skrip juga melakukan query validasi ulang untuk memastikan tidak ada lagi node yang menyimpan properti ini.

**Fase 4: Reporting (PR-06)**
Skrip mengekstrak daftar 5 node dengan `visual_pagerank_size` terbesar dan 5 terkecil dari Neo4j. Data ini, beserta informasi waktu eksekusi (`elapsed_ms`), statistik konvergensi GDS, dan sebaran nilai dirangkai menjadi laporan audit teks (ASCII Box layout) yang dicetak ke console terminal.

---

## 6. DIAGRAM ARSITEKTUR GDS PAGERANK PIPELINE

```mermaid
flowchart TD
    classDef init fill:#E3F2FD,stroke:#1565C0,stroke-width:2px,color:#0D47A1,rx:8,ry:8
    classDef neo4j fill:#E8F5E9,stroke:#2E7D32,stroke-width:2px,color:#1B5E20,rx:8,ry:8
    classDef process fill:#FFF3E0,stroke:#EF6C00,stroke-width:2px,color:#E65100,rx:8,ry:8
    classDef cleanup fill:#FCE4EC,stroke:#C2185B,stroke-width:2px,color:#880E4F,rx:8,ry:8

    Start([Start Pipeline]):::init
    
    subgraph Phase 1: Setup
        Connect[Driver Connection<br>& Preflight Check]:::neo4j
    end

    subgraph Phase 2: GDS Core
        Project[gds.graph.project<br>Load to RAM]:::process
        PageRank[gds.pageRank.write<br>Compute & Write 'pagerank_raw']:::process
        Drop[gds.graph.drop<br>Free RAM]:::process
    end

    subgraph Phase 3: Normalization
        Extract[MATCH min/max<br>'pagerank_raw']:::neo4j
        Scale[SET 'visual_pagerank_size'<br>Cypher Min-Max Math + Zero Guard]:::process
        Cleanup[REMOVE 'pagerank_raw'<br>Verify Cleanup]:::cleanup
    end

    subgraph Phase 4: Reporting
        Audit[Print Audit Report<br>Top/Bottom Nodes & Execution Time]:::init
    end

    Start --> Connect
    Connect --> Project
    Project --> PageRank
    PageRank --> Drop
    Drop --> Extract
    Extract --> Scale
    Scale --> Cleanup
    Cleanup --> Audit
```

---

## 7. PENJELASAN DETAIL DIAGRAM ARSITEKTUR

Diagram di atas mendeskripsikan secara linear aliran eksekusi di dalam skrip `calculate_pagerank.py`.

- **Phase 1 (Setup):** Ditandai dengan warna hijau (Neo4j interaksi ringan). Koneksi diverifikasi dan data base dihitung.
- **Phase 2 (GDS Core):** Rangkaian proses berwarna oranye merepresentasikan beban kerja berat (Heavy Analytics). Di sini terjadi pertukaran memori antara disk database dan in-memory catalog Neo4j GDS.
- **Phase 3 (Normalization):** Melibatkan proses penarikan metadata (`Extract`), kalkulasi berat di sisi server (`Scale`), dan prosedur housekeeping (`Cleanup`). Perhatikan bahwa proses `Scale` menangani matematika secara batch di dalam mesin database, bukan me-looping satu-satu di Python, memastikan efisiensi dan ACID compliance.
- **Phase 4 (Reporting):** Operasi ringkas untuk menghasilkan bukti eksekusi yang auditable bagi engineer.

---

## 8. STRUKTUR REPOSITORY RELEVAN

Penambahan pada PoC Task 2 terkait fitur ini:

```
poc-task2-neo4j-vector/
│
├─ calculate_pagerank.py                    <-- (Skrip Utama Baru)
│
├─ Markdown/
│  ├─ GDS_PageRank_Implementation_Plan.md   <-- (Blueprint Pipeline)
│  ├─ Final_Report_PoC_Task2_20260427.md    <-- (Laporan Ini)
│  └─ GDS-Pagerank-Log/
│     ├─ PR-01_Setup_Execution_Log.md       <-- (Audit Log per Fase)
│     ├─ PR-02_GDS_Core_Execution_Log.md
│     ├─ PR-03_MinMax_Execution_Log.md
│     ├─ PR-04_Scaling_Execution_Log.md
│     ├─ PR-05_Cleanup_Execution_Log.md
│     └─ PR-06_Reporting_Execution_Log.md
```

---

## 9. KESIMPULAN

Implementasi GDS PageRank Pipeline untuk Visual Node Sizing telah berhasil diselesaikan dan memenuhi seluruh Acceptance Criteria.

1. **Stabilitas Skema:** Properti `pagerank_raw` terbukti digunakan sementara dan dibersihkan dengan aman tanpa mengotori skema graf secara permanen.
2. **Keamanan Matematika:** Logika Cypher dengan kondisional `CASE WHEN` terbukti mampu menangani scenario edge-case (homogenious graph) dan memitigasi potensi crash *Division by Zero*.
3. **Efisiensi:** Mengingat pendekatan *server-side calculations* dan manajemen memori yang disiplin (Graph Projection Dropping), pipeline ini terbukti sangat cepat (waktu total < 1 detik untuk graf skala sampel) dan aman digunakan pada layanan terkelola berkapasitas memori rendah seperti AuraDB Free Tier.
4. **Siap Frontend:** Hasil akhir `visual_pagerank_size` memberikan rentang absolut (10.0 hingga 50.0) yang merupakan parameter idaman bagi library visualisasi graf (e.g., Vis.js), memastikan pemisahan logis (Separation of Concerns) antara analitik backend dan representasi frontend.

Sistem *Neo4j Vector Knowledge Graph* sekarang tidak hanya dapat melakukan reasoning secara generatif (via Edge Generation), tetapi juga dapat mengkuantifikasi struktur jejaringnya secara matematis.
