Γιατί Elasticsearch, OpenSearch, Kibana και Neo4j

12 λεπτά
Κοινό
αρχάριος, χωρίς απαιτούμενες γνώσεις
Διάρκεια
20 έως 30 λεπτά
Ενότητα
1/7
Στοχευόμενη δεξιότητα
να εντοπίζεις τον ρόλο κάθε εργαλείου του εργαστηρίου, να επιλέγεις το σωστό μοντέλο δεδομένων (πίνακας, έγγραφο, γράφος) ανάλογα με την ερώτηση

Ποιος το χρησιμοποιεί, και για ποιο λόγο

Όταν πληκτρολογείς τρεις λέξεις στο Google και η απάντηση έρχεται σε κλάσμα δευτερολέπτου, με διορθωμένα τα ορθογραφικά σου λάθη, δεν είναι μια βάση SQL που διατρέχει δισεκατομμύρια σελίδες: είναι ένα ανεστραμμένο ευρετήριο (inverted index), ένα λεξικό «λέξη → σελίδες που την περιέχουν». Τα Elasticsearch και OpenSearch εφαρμόζουν ακριβώς αυτή την αρχή στα δικά σου δεδομένα. Και όταν το Netflix σου προτείνει «όσοι αγάπησαν αυτό είδαν επίσης…», ή το Facebook σου προτείνει έναν φίλο ενός φίλου, πρόκειται για σχέσεις που διατρέχονται, όχι για γραμμές που φιλτράρονται: είναι η δουλειά μιας βάσης γράφων όπως το Neo4j.

ΠοιοςΕργαλείοΓια ποιο λόγο
WikipediaElasticsearchη γραμμή αναζήτησης όλων των άρθρων, σε όλες τις γλώσσες, ανεκτική σε ορθογραφικά λάθη
Netflix, Uber, SlackElasticsearch + Kibanaδισεκατομμύρια γραμμές αρχείων καταγραφής την ημέρα, διερευνώμενες σε πραγματικό χρόνο για να βρεθεί μια βλάβη μέσα σε λίγα δευτερόλεπτα
Stack Overflow, GitHubElasticsearchη αναζήτηση πλήρους κειμένου σε ερωτήσεις, απαντήσεις και κώδικα
AmazonOpenSearchο κινητήρας που δημιούργησε και συντηρεί η Amazon για να διατηρήσει μια 100% ανοιχτού κώδικα έκδοση, διατιθέμενος ως διαχειριζόμενη υπηρεσία στο AWS
NASANeo4jη βάση των «διδαγμάτων» 50 ετών αποστολών, συνδεδεμένων μεταξύ τους ώστε να βρεθεί ένα προηγούμενο μέσα σε λίγα βήματα
Κοινοπραξία ICIJ (Panama Papers)Neo4j11,5 εκατομμύρια έγγραφα και οι σύνδεσμοι μεταξύ εικονικών εταιρειών, στελεχών και τραπεζών, διερευνώμενοι σε γράφο από 370 δημοσιογράφους
eBay, WalmartNeo4jσυστάσεις σε πραγματικό χρόνο: «όσοι αγόρασαν αυτό…», υπολογιζόμενες ακολουθώντας σχέσεις αγοράς

Αυτό που έχουν κοινό αυτές οι εταιρείες: έχουν επίσης βάσεις SQL, για τις πληρωμές, τις παραγγελίες, τα τιμολόγια. Προσθέτουν έναν κινητήρα αναζήτησης δίπλα για να αναζητούν, και μια βάση γράφων δίπλα για να συνδέουν. Ακριβώς αυτό θα στήσεις σε αυτό το εργαστήριο, σε μικρή κλίμακα.

Οι ορισμοί

  • Τα Elasticsearch και OpenSearch χρησιμεύουν στην αποθήκευση εγγράφων JSON και στην ταχεία εκτέλεση αναζητήσεων κειμένου, ακόμη και με ορθογραφικά λάθη.
  • Τα Kibana και OpenSearch Dashboards δεν αποθηκεύουν δεδομένα: επιτρέπουν την εξερεύνησή τους και τη δημιουργία γραφημάτων και ταμπλό.
  • Το Neo4j είναι μια βάση δεδομένων προσανατολισμένη σε γράφους, κατάλληλη για σύνθετες σχέσεις όπως προαπαιτούμενα, συστάσεις και συνδέσμους μεταξύ χρηστών.
  • Η SQL παραμένει προτιμότερη για συναλλακτικά δεδομένα που απαιτούν ισχυρή συνέπεια, όπως πληρωμές και τιμολόγια.
  • Η βασική αρχή είναι να επιλέγεις το εργαλείο ανάλογα με την ερώτηση: αναζήτηση με λέξεις με Elasticsearch/OpenSearch, οπτικοποίηση με Kibana και εξερεύνηση συνδέσμων με Neo4j.

Σε μία εικόνα

Φαντάσου ένα μεγάλο διαδικτυακό σχολείο. Στην υποδοχή, μια βιβλιοθηκονόμος βρίσκει σε ένα δευτερόλεπτο όλα τα μαθήματα που μιλούν για «ανάπτυξη κοντέινερ», ακόμη κι αν έγραψες «αναπτυξη» χωρίς τόνο: αυτό είναι το Elasticsearch. Στον τοίχο, οθόνες δείχνουν την κίνηση του ιστότοπου σε πραγματικό χρόνο, τις σελίδες με σφάλμα, τις χώρες προέλευσης των επισκεπτών: αυτό είναι το Kibana, που δεν αποθηκεύει τίποτα αλλά σχεδιάζει ό,τι περιέχει το Elasticsearch. Στο γραφείο προσανατολισμού, μια σύμβουλος γνωρίζει τις σχέσεις μεταξύ των ανθρώπων: ποιος παρακολούθησε τι, ποιο μάθημα είναι προαπαιτούμενο ποιου άλλου, ποιοι μαθητές μοιάζουν μεταξύ τους: αυτό είναι το Neo4j. Και το OpenSearch; Είναι η δίδυμη βιβλιοθηκονόμος, εκπαιδευμένη στο ίδιο σχολείο με το Elasticsearch, προσληφθείσα από όσους θέλουν ένα 100% ανοιχτού κώδικα συμβόλαιο. Τέσσερα εργαλεία, δύο τρόποι ταξινόμησης της πληροφορίας: με λέξεις (μηχανή αναζήτησης) ή με συνδέσμους (γράφος).

Πώς λειτουργεί

Τα τέσσερα εργαλεία του εργαστηρίου

ΕργαλείοΈκδοση εργαστηρίουΡόλοςΤου μιλάς με
Elasticsearch9.5.3αποθηκεύει έγγραφα JSON και τα ανακτά μέσω κειμένου, φίλτρων, συγκεντρώσεωνQuery DSL (JSON), ES|QL
Kibana9.5.3διεπαφή ιστού του Elasticsearch: Dev Tools, Discover, Lens, ταμπλόκλικ, KQL, και Dev Tools για JSON
OpenSearch (+ Dashboards)3.8.0fork ανοιχτού κώδικα του Elasticsearch και του Kibana, ίδιο API σε ποσοστό 95%το ίδιο Query DSL, καθώς και SQL και PPL
Neo4j Community5.26βάση γράφων: κόμβοι, σχέσεις, ιδιότητεςCypher

Τα Elasticsearch και OpenSearch μοιράζονται τον ίδιο εσωτερικό κινητήρα, το Apache Lucene, και την ίδια αρχή: το ανεστραμμένο ευρετήριο (inverted index). Αντί να διαβάζει κάθε έγγραφο σε κάθε αναζήτηση, ο κινητήρας κατασκευάζει μία φορά για πάντα ένα λεξικό «λέξη → λίστα εγγράφων που την περιέχουν». Η αναζήτηση «docker kubernetes» ανάγεται τότε στη διασταύρωση δύο λιστών αναγνωριστικών, κάτι που παίρνει λίγα χιλιοστά του δευτερολέπτου σε εκατομμύρια έγγραφα. Το Neo4j κάνει το αντίθετο στοίχημα: αποθηκεύει τις σχέσεις ως φυσικούς δείκτες μεταξύ κόμβων, ώστε «οι φίλοι των φίλων μου» να υπολογίζονται ακολουθώντας βέλη, χωρίς join.

Το λεξιλόγιο, μεταφρασμένο από τη μία βάση στην άλλη

Κάθε κινητήρας εφευρίσκει τις δικές του λέξεις, αλλά συχνά αναφέρονται στην ίδια ιδέα όπως σε μια σχεσιακή βάση. Ο παρακάτω πίνακας μεταφράζει τους βασικούς όρους μεταξύ της κλασικής SQL, των μηχανών αναζήτησης και του γράφου.

Κλασική SQLElasticsearch / OpenSearchNeo4j (γράφος)Με απλά λόγια
βάση δεδομένωνcluster (σύνολο index)βάση γράφουόλο το περιεχόμενο που διαχειρίζεται ο διακομιστής
πίνακαςindexετικέτα κόμβου (label)μια συλλογή στοιχείων του ίδιου τύπου
γραμμή / εγγραφήέγγραφο (JSON)κόμβοςένα στοιχείο
στήληπεδίο (field)ιδιότηταένα χαρακτηριστικό του στοιχείου
σχήμα / DDLmappingελαστικό σχήμα (προαιρετικό)ο ορισμός των τύπων πεδίων
πρωτεύον κλειδί_id του εγγράφουταυτότητα του κόμβουτο μοναδικό αναγνωριστικό
ξένο κλειδί + joinχωρίς join: cours_id αποκανονικοποιημένοσχέση (-[:PREREQUIS_DE]->)ο σύνδεσμος μεταξύ δύο στοιχείων
index (B-tree) επιτάχυνσηςανεστραμμένο ευρετήριοindex σε μια ιδιότηταη δομή που επιταχύνει την αναζήτηση
SELECT … WHEREQuery DSL (JSON), ES|QLMATCH … WHERE … RETURNερώτημα στα δεδομένα
GROUP BY / συνάθροισησυγκεντρώσεις (aggs)count(), collect()ομαδοποίηση και μέτρηση
SQL (γλώσσα)Query DSL / ES|QL / KQLCypherη γλώσσα ερωτημάτων

Πρόσεξε τη λέξη «index». Στην SQL, ένα index είναι μια δομή επιτάχυνσης (B-tree) τοποθετημένη πάνω σε έναν πίνακα. Στο Elasticsearch, ένα index είναι το ισοδύναμο του ίδιου του πίνακα. Και το ανεστραμμένο ευρετήριο είναι κάτι ακόμη διαφορετικό: ο εσωτερικός μηχανισμός «λέξη → έγγραφα» που κάνει την αναζήτηση ακαριαία. Τρεις έννοιες για μία μόνο λέξη.

Το ίδιο παράδειγμα σε τρία μοντέλα

Ας πάρουμε τρεις έννοιες από το σχολείο μας: μαθήματα, μαθητές, κριτικές που αφήνουν οι μαθητές στα μαθήματα.

1. Σε SQL (πίνακες και joins) — τρεις κανονικοποιημένοι πίνακες, η πληροφορία δεν διπλασιάζεται ποτέ, οι σύνδεσμοι περνούν μέσα από ξένα κλειδιά:

sql
SELECT c.titre, AVG(a.note)
FROM cours c
JOIN avis a ON a.cours_id = c.id
JOIN etudiant e ON e.id = a.etudiant_id
WHERE e.ville = 'Montréal'
GROUP BY c.titre;

Τέλειο για τη συνέπεια (μια τροποποιημένη βαθμολογία τροποποιείται παντού), λιγότερο καλό για «όλα τα μαθήματα των οποίων η περιγραφή περιέχει ανάπτυξη»: το LIKE '%déploy%' διατρέχει ολόκληρο τον πίνακα.

2. Σε έγγραφα (Elasticsearch / OpenSearch) — ένα μάθημα είναι ένα ενιαίο έγγραφο JSON που ενσωματώνει ό,τι χρειάζεται η αναζήτηση, συμπεριλαμβανομένου του ονόματος του καθηγητή και της ήδη υπολογισμένης μέσης βαθμολογίας. Δες, ακριβώς όπως είναι, το πρώτο έγγραφο του index cours του εργαστηρίου:

json
{
  "id": "C0001",
  "titre": "Docker expliqué simplement",
  "description": "Dans ce cours accessible sans prérequis, vous apprenez à automatiser vos applications avec Docker. …",
  "categorie": "DevOps", "sujet": "Docker", "niveau": "debutant", "langue": "en",
  "prix": 129, "gratuit": false, "duree_heures": 5,
  "tags": ["docker", "linux", "helm", "devops"],
  "date_publication": "2024-08-14",
  "note_moyenne": 4.4, "nb_avis": 327,
  "professeur": { "id": "P001", "nom": "Karim Caron", "ville": "Gatineau" },
  "competences": ["Conteneurisation", "Intégration continue"]
}

Το όνομα του καθηγητή είναι αποκανονικοποιημένο (αντιγραμμένο σε κάθε μάθημα). Αν αλλάξει όνομα, θα χρειαστεί να επανευρετηριαστούν τα μαθήματά του: αυτό είναι το τίμημα της ακαριαίας αναζήτησης. Οι κριτικές ζουν σε ένα δεύτερο index, το avis, με το cours_id ως απλό πεδίο, χωρίς δυνατότητα join τη στιγμή του ερωτήματος.

3. Σε γράφο (Neo4j) — οι ίδιες έννοιες γίνονται κόμβοι, και οι σύνδεσμοι γίνονται σχέσεις πρώτης τάξης που φέρουν οι ίδιες ιδιότητες. Δες τρεις πραγματικές σχέσεις από τον γράφο του εργαστηρίου γύρω από το μάθημα C0001:

cypher
(:Etudiant {prenom: "Hugo"})-[:INSCRIT_A {progression: 100, note: 4}]->(:Cours {id: "C0001", titre: "Docker expliqué simplement"})
(:Cours {id: "C0001"})-[:PREREQUIS_DE]->(:Cours {id: "C0003", titre: "Docker : le guide complet"})
(:Professeur {prenom: "Karim", nom: "Caron"})-[:ENSEIGNE]->(:Cours {id: "C0001"})

Η ερώτηση «ποια μαθήματα παρακολούθησαν οι μαθητές που αγάπησαν το ίδιο μάθημα με εμένα;» γράφεται σε μία γραμμή Cypher και υπολογίζεται ακολουθώντας τρεις σχέσεις, εκεί όπου η SQL θα αλυσόδενε τρία joins και όπου το Elasticsearch απλά δεν θα ήξερε να απαντήσει.

ΕρώτησηΚαλύτερο εργαλείοΓιατί
«μαθήματα για ανάπτυξη κοντέινερ, ανεκτικά σε ορθογραφικά λάθη»Elasticsearch / OpenSearchανεστραμμένο ευρετήριο, γαλλικός αναλυτής, fuzzy
«κατανομή σφαλμάτων 500 ανά χώρα σε 30 ημέρες»Elasticsearch + Kibanaσυγκεντρώσεις και οπτικοποίηση σε πραγματικό χρόνο
«διαδρομή προαπαιτούμενων για να φτάσω στο μάθημα C0230»Neo4jδιάτρεξη σχέσεων, συντομότερη διαδρομή
«σύσταση μαθήματος βάσει παρόμοιων εγγραφών»Neo4jσυνεργατικό φιλτράρισμα = μοτίβο γράφου
«πληρωμή, τιμολόγιο, αυστηρή συνέπεια»SQL (εκτός εργαστηρίου)συναλλαγές ACID

Αρχιτεκτονική ενός τυπικού pipeline

Στην πραγματική ζωή, τα αρχεία καταγραφής φτάνουν συνεχώς (Filebeat, Logstash ή η ίδια η εφαρμογή) και η βάση γράφων τροφοδοτείται από το επιχειρησιακό σύστημα. Στο εργαστήριο, δύο εντολές αντικαθιστούν όλα αυτά: η importer στέλνει τα αρχεία NDJSON στο API _bulk του Elasticsearch, η charger-graphe εκτελεί ένα σενάριο Cypher που διαβάζει CSV. Οι δύο κόσμοι δεν επικοινωνούν μεταξύ τους: εσύ, ή η εφαρμογή σου, επιλέγεις σε ποιον θα θέσεις κάθε ερώτηση.

Βήμα προς βήμα

Τίποτα να πληκτρολογήσεις σε αυτό το μάθημα: το εργαστήριο ξεκινά στο μάθημα 03. Τα παρακάτω αποσπάσματα καταγράφηκαν από το εργαστήριο του μαθήματος, ώστε να ξέρεις τι θα βρεις μέσα.

  1. Το σύνολο δεδομένων: μια πλατφόρμα διαδικτυακών μαθημάτων. Ένας μόνο κόσμος τροφοδοτεί τους τρεις κινητήρες, για να συγκρίνεις τι κάνει καλύτερα ο καθένας.

    ΣύνολοΑκριβής όγκοςΠεριεχόμενο
    index cours504 έγγραφατίτλος, περιγραφή (γαλλικός αναλυτής), κατηγορία, θέμα, επίπεδο, τιμή, ετικέτες, μέση βαθμολογία, καθηγητής
    index avis609 έγγραφαβαθμολογία από 1 έως 5, κείμενο, όνομα, πόλη, χώρα, ημερομηνία, ψήφοι «χρήσιμο»
    index acces12.000 γραμμέςαρχεία καταγραφής ιστού από 2026-08-10 έως 2026-09-08: διαδρομή, κατάσταση HTTP, IP, χώρα, συσκευή, παραπομπή
    γράφος Neo4j872 κόμβοι · 3.712 σχέσειςCours 504, Etudiant 300, Professeur 30, Competence 22, Ville 16

    Αυτό που πρέπει να δεις: τα 504 μαθήματα του γράφου είναι τα ίδια με εκείνα του index cours (ίδια αναγνωριστικά C0001C0504). Θα μπορέσεις να αναζητήσεις ένα μάθημα στο Elasticsearch και μετά να εξερευνήσεις τα προαπαιτούμενά του στο Neo4j.

  2. Οι κατηγορίες είναι τέλεια ισορροπημένες. Μια συγκέντρωση terms στο categorie επιστρέφει:

    text
    Cloud 84 · DevOps 84 · Données 84 · Développement web 84 · IA 84 · Sécurité 84

    Και στα άλλα πεδία: niveau → debutant 252, avance 158, intermediaire 94· langue → fr 375, en 129· gratuit → 75 δωρεάν μαθήματα· 72 διακριτά θέματα (Docker, Kubernetes, Elasticsearch, Neo4j, React, AWS…)· 30 καθηγητές. Αυτό που πρέπει να δεις: στρογγυλοί και γνωστοί εκ των προτέρων αριθμοί, χρήσιμοι για να επαληθεύεις τα ερωτήματά σου στις ενότητες 2 και 3.

  3. Μια κριτική, όπως αποθηκεύεται. Πρώτο έγγραφο του index avis:

    json
    { "id": "A00001", "cours_id": "C0028", "etudiant": "Nathan", "ville": "Sherbrooke", "pays": "Canada",
      "note": 3, "texte": "Les vidéos sont bonnes, la partie théorique est dense.", "date": "2024-06-21", "utile": 33 }

    Αυτό που πρέπει να δεις: το cours_id είναι μια απλή συμβολοσειρά. Κανένα join δεν συνδέει αυτή την κριτική με το μάθημά της στο Elasticsearch· η εφαρμογή σου θα κάνει τη σύνδεση.

  4. Μια γραμμή αρχείου καταγραφής. Η πιο πρόσφατη του index acces:

    json
    { "id": "L012000", "@timestamp": "2026-09-08T23:39:29.000Z", "methode": "GET", "chemin": "/cours/C0430",
      "cours_id": "C0430", "categorie": "Cloud", "statut": 200, "octets": 168403, "duree_ms": 351,
      "ip": "169.199.97.7", "pays": "CA", "appareil": "desktop", "navigateur": "Chrome", "referent": "direct" }

    Στις 12.000 γραμμές: 10.829 σε 200, 403 σε 404, 355 σε 301, 235 σε 304, 122 σε 500, 56 σε 503. Αυτό που πρέπει να δεις: το πεδίο @timestamp, απαραίτητο για το Kibana Discover για τον άξονα του χρόνου (ενότητα 4).

  5. Ο γράφος, μετρημένος ανά ετικέτα και τύπο σχέσης. Πραγματικό αποτέλεσμα δύο ερωτημάτων Cypher:

    text
    Cours 504 · Etudiant 300 · Professeur 30 · Competence 22 · Ville 16
    INSCRIT_A 1654 · COUVRE 994 · ENSEIGNE 504 · HABITE 330 · PREREQUIS_DE 230

    Αυτό που πρέπει να δεις: 1.654 εγγραφές για 300 μαθητές, δηλαδή περίπου 5,5 μαθήματα ανά μαθητή. Αυτό το πλέγμα είναι που θα κάνει ενδιαφέρουσες τις συστάσεις της ενότητας 7.

Αν κολλήσεις

  • «Ξέρω SQL, γιατί να μην τα κάνω όλα με PostgreSQL;» → Μπορείς, μέχρι ένα σημείο. Η PostgreSQL ξέρει να κάνει αναζήτηση πλήρους κειμένου και αναδρομικά ερωτήματα. Αλλά μόλις θελήσεις ανοχή σε ορθογραφικά λάθη, ταξινόμηση κατά συνάφεια, συγκεντρώσεις σε εκατομμύρια γραμμές σε πραγματικό χρόνο ή διατρέξεις γράφου μεταβλητού βάθους, κάθε εξειδικευμένος κινητήρας κάνει τη δουλειά σε λίγα χιλιοστά του δευτερολέπτου εκεί όπου η SQL απαιτεί εξωτικά index και δυσανάγνωστα ερωτήματα. Η σωστή αντανακλαστική κίνηση: SQL για την πηγή αλήθειας των συναλλαγών, Elasticsearch δίπλα για αναζήτηση, Neo4j δίπλα για σύνδεση.

  • «Elasticsearch ή OpenSearch, πρέπει να διαλέξω τώρα;» → Όχι. Το μάθημα σε βάζει να δουλέψεις στο Elasticsearch· η ενότητα 5 ξαναπαίζει τα ίδια ερωτήματα στο OpenSearch και απαριθμεί τις διαφορές (μια χούφτα). Ό,τι μαθαίνεις ισχύει και για τα δύο.

  • «Το Kibana είναι βάση δεδομένων;» → Όχι, και είναι συχνή σύγχυση. Το Kibana αποθηκεύει μόνο τη διαμόρφωσή σου (ταμπλό, προβολές) σε ένα κρυφό index του Elasticsearch. Όλα τα δεδομένα που βλέπεις προέρχονται από το Elasticsearch· αν το Elasticsearch είναι σταματημένο, το Kibana εμφανίζει «Kibana server is not ready yet» (μάθημα 04).

Να θυμάσαι

  • Τα Elasticsearch και OpenSearch ταξινομούν την πληροφορία με λέξεις (ανεστραμμένο ευρετήριο)· το Neo4j την ταξινομεί με συνδέσμους (φυσικές σχέσεις). Τα Kibana και OpenSearch Dashboards δεν ταξινομούν τίποτα: εμφανίζουν.
  • Ένα έγγραφο JSON είναι αποκανονικοποιημένο: ενσωματώνει ό,τι χρειάζεται για την αναζήτηση, με το τίμημα των διπλασιασμών. Ένας πίνακας SQL κανονικοποιεί· ένας γράφος συνδέει.
  • Θέσε την ερώτηση πριν επιλέξεις το εργαλείο: «ποια έγγραφα μιλούν για…» → μηχανή αναζήτησης· «πώς συνδέεται το X με το Y» → γράφος.
  • Το σύνολο δεδομένων του μαθήματος: 504 μαθήματα, 609 κριτικές, 12.000 προσβάσεις, 872 κόμβοι και 3.712 σχέσεις, με τα ίδια αναγνωριστικά μαθημάτων παντού.
  • Οι εκδόσεις του εργαστηρίου είναι σταθεροποιημένες (9.5.3 / 3.8.0 / 5.26): κάθε αποτέλεσμα που παρουσιάζεται στο μάθημα προήλθε ακριβώς από αυτές τις εκδόσεις.

Για να πας πιο μακριά

Η λέξη «index» δηλώνει δύο διαφορετικά πράγματα: στην SQL, μια δομή επιτάχυνσης (B-tree) προσαρτημένη σε έναν πίνακα· στο Elasticsearch, το ισοδύναμο του ίδιου του πίνακα, χωρισμένο σε shards (αυτόνομα index Lucene). Η ενότητα 2, μάθημα 01, ξαναπιάνει αυτό το λεξιλόγιο στην πράξη πάνω στο εργαστήριο.