Sales7 min read1358 words

Public Sector Case Study

Burak Kaşıkcı

PlusClouds Author

Cloud & SaaS

Public Sector Case Study

BusinessDesk Kimdir?

BusinessDesk, 2008 yılından bu yana Yeni Zelanda siyasi ekonomisini ve listelenmiş ve listelenmemiş işletmelerinin durumunu ele almaktadır.
BusinessDesk'in binlerce bireysel abonesi ve 150'den fazla kurumsal ve hükümet abonesi bulunmaktadır.

Daha fazla bilgi için https://nextdeveloper.com/casestudy/businessdesk

Kamu Sektörü Vaka Çalışması

Devletle ortaklaşa yaptıkları bir projede, açıldığı günden bu yana biriktirdikleri bilgiyle binlerce haber bağlantısı aracılığıyla insanları, şirketleri ve hatta bakanlıkları birbirine bağlamak istediler ve bu konuda nasıl harekete geçebileceğimizi incelemeye başladık.
Buradaki ana amaç, bir kişinin nerede ve kiminle çalıştığını görmek ve iş yeri ilişkileri dışında kimlerle temas halinde olduğunu haberler aracılığıyla görmektir.

Problem

Buradaki ana problem, ilişkilerin nasıl olacağı, bu verilerin nerede ve nasıl saklanacağı ve bu bilginin binlerce haberde nasıl oluşturulacağı konularını netleştirmekti.

Binlerce haber, yüzlerce insan ve bu kadar çok şirketle ne yapabileceğimizi düşünmeye başladık.

İlk bakışta, projede kullandığımız MySql veritabanı ile bunu kolayca çözebileceğimiz görünüyordu. Şirket bağlantılarını insanlardan ve oradan diğer insanlardan eşleştiriyoruz. Tamam burada, peki ya haberler? Burada, sıradan bir arama işleminin bizi kurtarmayacağı, kurtarsa bile 2. seviyeden sonra ilişkilerde performans sorunları yaratacağı için ayrı bir yapıda ilerlememiz gerektiği yönünde sesler yükseldi.

Çözüm

Öncelikle, bu kişilerin ve şirketlerin ilişkilerinin nasıl olacağı kısmını çözmek gerekiyordu. Burada, ilk amacımız insanların birbirleriyle ve çalıştıkları şirketlerle olan iş ilişkilerini bulmaktı.

Sahip olduğumuz bilgilerle, insanların aktif olarak çalıştıkları ve daha önce çalıştıkları yerlere ulaşabildik. Bu, bizim için ilk ve en kolay bağlantıydı. Bunu doğrudan ulaşabileceğimiz bir seviye 1 bağlantısı olarak cebimize koyduk.

Tüm kullanıcıların bilgisini aynı mantıkla oluşturduktan sonra, tüm şirketlerin orada çalışan insanlarla olan bağlantısını da kurduk.

Bu 1. seviye ilişkilerden sonra, biraz daha detaya inip kişinin çalıştığı şirket üzerinden meslektaşlarını bulma zamanı geldi.

Burada MySql bizim için yeterli olmayacağından, Neo4j - graph database ile devam etmeye karar verdik. Neo4j'nin bu ve benzeri işler için oluşturulduğundan ve üretilen verilerin kullanımı ve gösterimi sırasında sağladığı kolaylıklardan emin olduktan sonra burada bir adım atmaya başladık.

Öncelikle, burada tüm insanları “People”, şirketleri “Entity” ve haberleri “Story” düğümleri ile oluşturduk.

Tüm bu düğümler, birbirleriyle ilişkilendirebileceğimiz bilgileri gerektiriyordu.

“People” düğümü için, aktif olarak ve geçmişte çalıştığı şirketleri “EntityIds” adlı bir diziye atadık. Bu ilişki ile aslında 1. seviye bağlantılarımızı tamamladık.

İlk bağlantılarımızı oluşturup Neo4j'ye bıraktıktan sonra, biraz daha karmaşık olan haberlere geçme zamanı geldi. Burada, haberlerdeki kişi ve şirket isimlerini bir bütün metin olarak aradık ve hangi kişi ve şirket isminin hangi haberde geçtiğini bulduk.

“Story” düğümünde “PeopleIds” ve “EntityIds” adında 2 dizi oluşturduk ve haberle bağlantılı bulduğumuz bilgileri atadık.

Daha teknik kısımları öğrenmek istiyorsanız, buradan devam edebilirsiniz.

Sonuç

Neo4j'ye tekrar döndüğümüzde, insanlar, şirketler ve haberler için düğümlerimiz ve ilgili ilişkilerimiz hazırdı.

İlk “People” düğümündeki “EntityIds” sayesinde, aşağıdaki ilişkilere doğrudan bağlantımız var.

  • İnsanlar ve çalıştıkları tüm şirketler
  • Şirketler ve burada çalışan tüm insanlar

Şu ana kadar hep böyle seviye 1 ilişkilerden bahsettim. İlk seviye 2 bağlantımıza meslektaşlık yoluyla erişiyoruz.

Yani; Öncelikle bir kişinin çalıştığı şirkete ulaşıyoruz, ardından bu şirketteki çalışanlara ve ilk 2. seviye bağlantımıza ulaşıyoruz.

Aynı mantıkla, meslektaşın çalıştığı diğer yerler üzerinden Neo4j aracılığıyla 3. ve 4. seviye bağlantılarımıza kolayca erişebiliriz.

Haberler için yine iş arkadaşlığı mantığıyla, “PeopleIds” ve “EntityIds” serilerindeki bilgileri kullanarak, buradaki tüm kişi ve şirketlerin 2. seviye bağlantılarını ilk olarak kurduk.

İş arkadaşlığına benzer bir mantıkla, daha önce kurduğumuz 2. seviye bağlantılar aracılığıyla bu ilişkiyi kurduğumuz kişi veya şirketlerle derinlemesine bir ilişki kurabildik.

Dikkat Edilmesi Gereken Bazı Şeyler

  • Burada, ilk ilişkiden sonra, yeni haber, kişi veya şirket değişikliği durumunda sistemin düzgün bir şekilde devam edebilmesi için, her yeni kayıt için bu sistemi tetikleyecek bir iş yaptık, böylece yalnızca değişen veriler işlenir.

  • Neo4j'de performans sorunları yaşamamak veya sonsuz bir döngüye düşmemek için verilerin doğruluğunu kontrol ettik. Ve Neo4j'deki ilişkiler için en uygun ve optimize edilmiş sorguları yazdık.

  • Projemiz ve Neo4j içinde, web sitesinde göstereceğimiz bilgileri olabildiğince basit tuttuk. Sonrasında, izleyicinin kodlar arasında boğulmadan rahatça sonuca ulaşabilmesi için gerekli yazılım ilkelerini takip ederek doğru bir kodlama ile sonuca ulaştık.


Neo4j'yi Nasıl Kullanıyoruz, Daha Fazla Teknik Bilgi

Sistemimizde people, entities, ministers ve stories olmak üzere dört farklı model bulunmaktadır. Bu modellerin tümü yönetim panelinden eklenebilir ve güncellenebilir. Model düğümleri arasındaki bağlantıları toplamak için kullanılan özel türde ilişkiler (kenarlar) de vardır.

Öncelikle, bir hikaye diğer hikaye türleri hariç her tür modelle ilişkilendirilebilir. Eğer bir hikayenin içeriği (gövde metni) bir kişi, varlık veya bakan ismini içeriyorsa, hikaye bu modelle bağlantı kurar. Bu özel bağlantı türüne REL_STORY denir.

Aşağıdaki resimde görüldüğü gibi, 24553 id numaralı hikayenin 3 bağlantısı vardır. Varlıkları kırmızı düğümlerle ve insanları mavi düğümlerle temsil ediyoruz. Dolayısıyla, id numarası 25 olan kişinin bu hikaye aracılığıyla iki diğer varlıkla bağlantılı olduğunu söyleyebiliriz.

Açıklama

Varlıklar, insanların şu anda çalıştıkları veya geçmişte çalıştıkları şirketlerdir. İkinci tür ilişki için bu iş ilişkisine REL_EMPLOYMENT denir. Bu tür ilişki sadece insanlar ve varlıklar arasında var olabilir.

Neo4j Servisi

Ana web uygulamamız bir MySQL veritabanı kullanıyor ve Neo4j sunucumuzdan farklı bir sunucuda bulunuyor. Bu nedenle, Neo4j sunucumuzda Laravel ile başka bir proje uyguladık. Bu yeni uygulama, ana web uygulamamızdan gelen istekleri kabul eder ve Neo4j'ye yönlendirir. Neo4j'den sonuçları aldıktan sonra, bu sonucu ana web uygulamamıza gönderir.

Ana uygulama, düğüm türü ve id'si ile bağlı düğüm id numaraları ve türlerini içeren bir HTTP isteği gönderir. Neo4j Laravel uygulaması, ana uygulamadan alınan verileri kullanarak düğümün ilişkilerini yeniler. Neo4j, verilerin MySQL sunucusunda orijinal olarak depolandığı id'leri bilir.

İşte id'leri 1, 2 ve 3 olan kişileri id'si 1 olan hikayeyle bağlayan örnek HTTP istek gövdemiz. Ayrıca ilişkinin türü belirtilmelidir.

{
“nodeClass”: “Story”,
“relatedNodeClass”: “People”,
“nodeID”: 1,
“relatedNodeIDs”: [1,2,3],
“relationType”: “REL_STORY”
}

Gözlemci Fonksiyonlar & İşler

Neo4j verilerini gözlemci sınıflar ve işler ile senkronize ediyoruz. Bu modellerde bir şey değiştiğinde, Neo4j sunucusunu güncellemeliyiz. MySQL araması bir web sayfası yüklemesi için çok fazla zaman aldığından bazı işlemler için iş kullanmamız gerekiyor. Gözlemciler görevleriyle birlikte aşağıda listelenmiştir;

Hikaye gözlemcisi: Yeni bir hikaye eklendiğinde veya hikayenin gövdesi değiştirildiğinde, o hikayenin gövdesinde kişi, varlık ve bakan isimlerini aramak için bir MySQL arama işi oluşturun. Arama sonucu elde edildikten sonra, Neo4j'ye gönderin.

Kişi gözlemcisi: Yeni bir kişi eklendiğinde veya kişinin adı değiştirildiğinde, o kişinin adını aramak için hikaye gövdelerinde bir MySQL arama işi oluşturun. Arama sonucu elde edildikten sonra, Neo4j'ye gönderin. Eğer kişinin iş geçmişi değişirse, MySQL'den tüm iş geçmişini alın ve Neo4j'ye gönderin. Ayrıca, kişinin organizasyonu da iş geçmişine eklenir.

Varlık gözlemcisi: Yeni bir varlık eklendiğinde veya varlığın adı değiştirildiğinde, o kişinin adını aramak için hikaye gövdelerinde bir MySQL arama işi oluşturun. Arama sonucu elde edildikten sonra, Neo4j'ye gönderin.

Bakan gözlemcisi: Yeni bir varlık eklendiğinde veya varlığın adı değiştirildiğinde, o kişinin adını aramak için hikaye gövdelerinde bir MySQL arama işi oluşturun. Arama sonucu elde edildikten sonra, Neo4j'ye gönderin.

Cypher Sorguları

Tüm ilişki verileri Neo4j'de depolandıktan sonra, match sorgularını kullanarak bağlantıları elde edebiliriz. Bu match sorguları, SQL'deki select sorguları gibi çalışır. Bu fonksiyonlar aşağıda listelenmiş ve açıklanmıştır;

getConnectedThroughStories()

Bu fonksiyon, giriş olarak person id, entity id veya minister id alır ve bu giriş modeline hikayeler aracılığıyla bağlı olan diğer tüm insanlar, varlıklar ve bakanları döndürür. Bu bağlantının amacı, aynı hikayelerde bahsedilen bireyleri bulmaktır. Örneğin, aşağıdaki sorgu, id'si 25 olan kişiyle hikayeler aracılığıyla bağlantılı olan tüm varlıkları alır. Bu sorgu ile herhangi bir kombinasyon yapabiliriz. Örneğin, belirli bir varlığa bağlı tüm bakanları da seçebiliriz.

MATCH (n:People)-[r1:REL_STORY]-(s:Story)-[r2:REL_STORY]-(m:Entity)
WHERE n.source_id = 25
RETURN DISTINCT m

getConnectedThroughEmployment()

Bu fonksiyon, giriş olarak person id alır ve bu giriş kişisine entities aracılığıyla bağlı olan diğer tüm insanları döndürür. Bu bağlantının amacı, ortak iş geçmişine sahip insanları bulmaktır. Örneğin, aşağıdaki sorgu, iş geçmişiyle verilen kişiye bağlı olan diğer tüm insanları alır.

MATCH (n:People)-[r1:REL_EMPLOYMENT]-(s:Entity)-[r2:REL_EMPLOYMENT]-(m:People)
WHERE n.source_id = 25
RETURN DISTINCT m

getConnectedEmployers()

Bu fonksiyon, giriş olarak person id alır ve doğrudan bağlı olan tüm entities döndürür. Bu bağlantının amacı, kişinin geçmişte ilişkili olduğu işverenleri bulmaktır. Örneğin, aşağıdaki sorgu, verilen kişinin şu anda çalıştığı ve daha önce çalıştığı tüm varlıkları alır.

MATCH (n:People)-[r:REL_EMPLOYMENT]-(m:Entity)
WHERE n.source_id = 25
RETURN DISTINCT m

getConnectedEmployees()

Bu fonksiyon, giriş olarak entity id alır ve doğrudan bağlı olan tüm people döndürür. Bu bağlantının amacı, varlığın geçmişte ilişkili olduğu çalışanları (insanları) bulmaktır. Örneğin, aşağıdaki sorgu, verilen varlığın şu anda çalıştırdığı ve daha önce çalıştırdığı tüm insanları alır.

MATCH (n:Entity)-[r:REL_EMPLOYMENT]-(m:People)
WHERE n.source_id = 12
RETURN DISTINCT m

Sıkça Sorulan Sorular

What was the goal of the Public Sector Case Study and how did it connect people, companies and ministries?

The main purpose was to see where and with whom a person works and to see who he or she has contact with other than workplace relations through news. It was done in partnership with the state and connected through thousands of news links.

Why did they move from MySQL to Neo4j for handling relationships?

They initially considered solving the problem with MySQL, but an ordinary search would not adequately handle deeper relationships beyond the first level and could cause performance problems. They chose Neo4j because a graph database handles complex connections more efficiently.

What are the node models and main relationships used in the Neo4j implementation?

There are four models: People, Entity, Ministers, and Stories. The implementation creates People, Entity and Story nodes, and uses REL_STORY to connect stories with people and entities, and REL_EMPLOYMENT to link people with entities.

How are news stories used to connect people and entities?

If a story’s content includes the name of a person, entity or minister, the story connects to that model. In Story nodes, arrays named PeopleIds and EntityIds store the connections found from the news, enabling list-based and deeper connections.

How does the Neo4j Service interact with the main MySQL-based application?

The main web application runs on MySQL on a separate server, and a Neo4j via Laravel handles requests from it. The main app sends an HTTP request with the node type, id and related node IDs; the Neo4j service refreshes the relations and only uses the IDs stored in MySQL.

What are the main Cypher queries used to get connections and what do they do?

Cypher queries are used to retrieve connections such as getConnectedThroughStories, which returns all entities or ministers connected through stories to a given person, entity, or minister; getConnectedThroughEmployment returns people connected via shared employment; getConnectedEmployers returns entities connected to a person; and getConnectedEmployees returns people connected to an entity.

What are observer functions and jobs, and how do they keep Neo4j in sync?

Observers and jobs synchronize Neo4j data with changes in the MySQL-backed models. The story observer creates a MySQL search job when a story is added or changed, the people/entity/minister observers similarly trigger searches and update Neo4j with the results.

What are some considerations when implementing this Neo4j-based solution?

One consideration is to trigger updates or deletions so the system continues to function when new data changes. It is also important to check data accuracy to avoid performance problems or infinite loops in Neo4j, and to keep displayed information simple with proper coding so users can access results easily.

İlgili Okumalar

Etiketlenen yazılar:

LeadOcean ve PlusClouds CRM Entegrasyonu: Otomatik Pipeline Kurulumu
Sales

LeadOcean ve PlusClouds CRM Entegrasyonu: Otomatik Pipeline Kurulumu

Bu rehberde; operasyonel yükü minimuma indiren bir yöntemi, yani LeadOcean üzerinde toplanan nitelikli verileri PlusClouds CRM ekosistemine otomatik olarak aktarmanın yolunu inceleyeceğiz. "Workspace Pusher" mekanizmasını kullanarak uçtan uca dijital bir köprü kuracak ve satış süreçlerinizi nasıl tam otomatik hale getirebileceğinizi adım adım ele alacağız.

WhatsApp Otomasyonu: Lead’leri Satışa Dönüştürmenin Yeni Yolu
Sales

WhatsApp Otomasyonu: Lead’leri Satışa Dönüştürmenin Yeni Yolu

Dijital dünyada rekabet artık sadece “daha fazla lead toplamak” üzerinden ilerlemiyor. Asıl fark yaratan, elde ettiğiniz lead’lere ne kadar hızlı, doğru ve kişiselleştirilmiş şekilde ulaştığınız. Bu noktada WhatsApp, yüksek etkileşim oranlarıyla en güçlü iletişim kanallarından biri olurken; n8n gibi araçlar sayesinde bu süreci tamamen otomatik ve ölçeklenebilir hale getirmek mümkün. Bu yazıda, n8n kullanarak WhatsApp otomasyonu kurmayı, Eaglet ve Leadocean gibi platformlardan gelen lead’leri satışa dönüştürmeyi ve bu süreci nasıl optimize edebileceğinizi detaylı şekilde ele alıyoruz.

2026’da WhatsApp ile Affiliate Gelir
Sales

2026’da WhatsApp ile Affiliate Gelir

2026 itibarıyla affiliate marketing artık sadece trafik üretmekle ilgili değil. Asıl farkı yaratan şey, o trafiği doğrudan satışa dönüştürebilmek. İşte burada WhatsApp devreye giriyor. 2026’da WhatsApp ile Affiliate Gelir nasıl elde edilir? E-posta açılma oranları düşerken, WhatsApp mesajlarının okunma oranı %90’ların üzerinde. Yani doğru stratejiyle WhatsApp, affiliate gelir için en güçlü “son temas noktası” haline geliyor. Ama burada kritik fark şu: Manuel mesaj atanlar değil, otomasyon kuranlar kazanıyor.

PlusClouds Affiliate ile Pasif Gelir (2026 Rehberi)
Sales

PlusClouds Affiliate ile Pasif Gelir (2026 Rehberi)

Dijital dünyada trafik üretmek bir beceri olabilir. Ancak 2026 itibarıyla asıl mesele trafik değil, trafiği gelire dönüştürme sistemi kurmak. Affiliate marketing (satış ortaklığı) yıllardır var. Fakat artık Amazon’dan düşük komisyonlu ürün satma dönemi kapandı. Gerçek kazanç; yüksek sepet tutarlı, B2B SaaS odaklı ve sürekliliği olan sistemlerde. İşte tam bu noktada PlusClouds devreye giriyor. 2026’da PlusClouds ile pasif gelir imparatorluğu kurmak artık çok basit. PlusClouds yalnızca bir bulut bilişim sağlayıcısı değil; affiliate’ler için yüksek komisyonlu, ölçeklenebilir ve araç destekli bir gelir ekosistemi sunuyor.