Ερευνητικό εργαστήριο 1 — Elasticsearch: ένα index, ένα έγγραφο, ένα ερώτημα GET

Καθοδηγούμενη πρακτική13 λεπτά
Διάρκεια
20 λεπτά
Ενότητα
1/7
Προαπαιτούμενα
το εργαστήριο τρέχει (η etat δείχνει (healthy) παντού), το Kibana Dev Tools ανοιχτό
Θα φτιάξεις
ένα δικό σου index, pratique-mini, με δύο έγγραφα που θα διαβάσεις, θα συμπληρώσεις, θα αναζητήσεις και θα διαγράψεις
Παραδοτέο
η απάντηση του GET pratique-mini/_doc/1 μετά το βήμα 5, με τα τρία της πεδία

Πώς να διαβάσεις αυτή τη σελίδα. Οκτώ βήματα, ένα ερώτημα τη φορά. Για κάθε ένα: το ερώτημα που πληκτρολογείς, η ακριβής απάντηση του εργαστηρίου, και τι πρέπει να προσέξεις μέσα σε αυτήν. Πληκτρολόγησε μόνος σου κάθε ερώτημα (όχι αντιγραφή-επικόλληση): γράφοντας PUT, GET, _doc είναι που οι λέξεις μπαίνουν στο μυαλό. Τα πλαίσια «Για να κατανοήσεις καλά» είναι προαιρετικά· άνοιξέ τα αν κάποιο βήμα σου αφήνει αμφιβολία. Αν το εργαστήριο δεν έχει ξεκινήσει, γύρνα στην καθοδηγούμενη πρακτική: η ενότητα Εν συντομία δίνει τις εντολές, μαζί με το kit (https://github.com/hrhouma2/aiopsatlas-recherche-graphes-labo-fr).

Στόχος

Η καθοδηγούμενη πρακτική σε έβαλε να φορτώσεις 504 μαθήματα, 609 κριτικές και 12.000 γραμμές αρχείου καταγραφής με τη μια, μέσω ενός σεναρίου. Είδες τους αριθμούς, αλλά δεν έχεις γράψει ακόμα τίποτα μόνος σου. Εδώ ξεκινάς από το μηδέν: ένα άδειο index που δημιουργείς εσύ, μια πρώτη καρτέλα που αποθηκεύεις μέσα του, που ξαναδιαβάζεις, που συμπληρώνεις, μετά μια δεύτερη, μια αναζήτηση, μια διαγραφή. Στο τέλος, ξέρεις τι είναι ένα index και ένα έγγραφο επειδή έφτιαξες ένα, όχι επειδή σου το είπαν.

Το λεξιλόγιο σε μία εικόνα

Ένα index είναι μια ντουλάπα. Ένα έγγραφο είναι μια καρτέλα αποθηκευμένη μέσα στην ντουλάπα: ένα μικρό κείμενο JSON με πεδία. Κάθε καρτέλα έχει έναν αριθμό, το _id της, που επιτρέπει να τη βρεις απευθείας χωρίς αναζήτηση. Δεν χρειάζεται να δηλώσεις τις στήλες εκ των προτέρων: η πρώτη καρτέλα που αποθηκεύεται δημιουργεί το mapping (το σχέδιο της ντουλάπας) μόνη της.

ElasticsearchΚλασική βάση SQLΣε αυτή την πρακτική
indexπίνακαςpratique-mini
documentγραμμή{"titre": "Mon premier document"}
πεδίοστήληtitre, auteur, note
_idπρωτεύον κλειδί1, 2
mappingσχήμα του πίνακα (CREATE TABLE …)δημιουργείται αυτόματα στο βήμα 3
_sourceη γραμμή όπως την έγραψεςαυτό που σου επιστρέφει το GET _doc/1

Πού πληκτρολογείς, και πώς να διαβάσεις ένα ερώτημα

Άνοιξε το http://localhost:5601, μενού ☰ → ManagementDev Tools. Ο αριστερός πίνακας δέχεται τα ερωτήματα, ο δεξιός εμφανίζει την απάντηση. Στέλνεις με Ctrl + Enter (Cmd + Enter σε macOS) ή το κουμπί ▶ δεξιά της γραμμής.

Κάθε ερώτημα έχει την ίδια μορφή: ένα ρήμα, μια διαδρομή, και μερικές φορές ένα σώμα JSON από κάτω.

ΡήμαΤι κάνειΙσοδύναμο SQL
GETδιάβασμα, χωρίς να αλλάζει τίποταSELECT
PUTδημιουργία, ή πλήρης αντικατάστασηCREATE TABLE, INSERT (ή αντικατάσταση της γραμμής)
POSTενέργεια: ενημέρωση, αναζήτηση με σώμαUPDATE
DELETEδιαγραφήDROP TABLE, DELETE

Η διαδρομή λέει πάνω σε τι ενεργείς: pratique-mini (η ντουλάπα), pratique-mini/_doc/1 (η καρτέλα νούμερο 1 της ντουλάπας), pratique-mini/_search (αναζήτηση μέσα στην ντουλάπα). Οι λέξεις που ξεκινούν με _ είναι εντολές του Elasticsearch, όχι δικά σου ονόματα.

Βήμα 1 — Δημιουργία της ντουλάπας, άδειας

text
PUT pratique-mini

Τι ζητάει το ερώτημα: δημιούργησε ένα index με το όνομα pratique-mini. Τίποτα άλλο: όχι στήλες, όχι περιεχόμενο.

json
{
  "acknowledged": true,
  "shards_acknowledged": true,
  "index": "pratique-mini"
}

Τι να προσέξεις: "acknowledged": true, «έγινε», και το όνομα σε ηχώ. Το σήμα πάνω δεξιά της απάντησης λέει 200 - OK.

Για να κατανοήσεις καλά
  • Γιατί pratique- μπροστά; Όλα τα index που δημιουργείς σε αυτό το μάθημα φέρουν αυτό το πρόθεμα. Έτσι το GET _cat/indices/pratique-*?v απαριθμεί μόνο ό,τι είναι δικό σου και τίποτα άλλο, και τα cours, avis, acces μένουν ανέγγιχτα.
  • Ένα όνομα index είναι με πεζά, χωρίς κενό ούτε κεφαλαίο ούτε /. Το Pratique-Mini θα απορριπτόταν.
  • Μια δεύτερη φορά το ίδιο ερώτημα απαντά 400 με resource_already_exists_exception: η ντουλάπα υπάρχει ήδη. Δεν είναι βλάβη, είναι απάντηση.

Βήμα 2 — Να τη δεις, και να διορθώσεις το χρώμα της

text
GET _cat/indices/pratique-mini?v

Τι ζητάει το ερώτημα: μια γραμμή περίληψης για αυτό το index, με τη γραμμή κεφαλίδας (?v, verbose).

text
health status index         uuid                   pri rep docs.count docs.deleted store.size pri.store.size dataset.size
yellow open   pratique-mini YHjAfGXBTwSZcl7CLcc2jw   1   1          0            0       227b           227b         227b

Τι να προσέξεις: docs.count 0, η ντουλάπα είναι άδεια. Και health yellow με rep 1: το Elasticsearch έχει προβλέψει ένα αντίγραφο ασφαλείας (ένα replica) του index σου σε ένα δεύτερο μηχάνημα, και το εργαστήριο έχει μόνο ένα. Το αντίγραφο δεν μπορεί να τοποθετηθεί πουθενά, εξ ου και το κίτρινο. Τα τρία index του kit είναι πράσινα επειδή το mapping τους ορίζει number_of_replicas: 0. Κάνε το ίδιο, με ένα ερώτημα:

text
PUT pratique-mini/_settings
{
  "index": { "number_of_replicas": 0 }
}
json
{
  "acknowledged": true
}

Ξαναπληκτρολόγησε GET _cat/indices/pratique-mini?v:

text
health status index         uuid                   pri rep docs.count docs.deleted store.size pri.store.size dataset.size
green  open   pratique-mini YHjAfGXBTwSZcl7CLcc2jw   1   0          0            0       227b           227b         227b

Τι να προσέξεις: green, rep 0. Το δικό σου uuid θα είναι διαφορετικό: είναι ο εσωτερικός αναγνωριστικός κωδικός του index, τραβηγμένος τυχαία κατά τη δημιουργία.

Για να κατανοήσεις καλά
  • Το κίτρινο δεν σημαίνει χαλασμένο. Ένα κίτρινο index διαβάζεται και γράφεται κανονικά. Είναι μια προειδοποίηση: «το αντίγραφο ασφαλείας που ζήτησες δεν υπάρχει». Σε ένα μόνο μηχάνημα, δεν μπορεί να υπάρξει.
  • Όσο το index σου ήταν κίτρινο, το GET _cluster/health έλεγε "status": "yellow" για ολόκληρο το cluster: το χρώμα του cluster είναι το χειρότερο χρώμα από τα index του. Αυτή είναι η εξήγηση της βλάβης «yellow» του καταλόγου από το μάθημα 04.
  • Το GET pratique-mini (χωρίς _cat) επιστρέφει την πλήρη καρτέλα του index: "mappings": { } (άδειο, καμία καρτέλα αποθηκευμένη) και "settings" με το number_of_replicas.

Βήμα 3 — Αποθήκευση μιας πρώτης καρτέλας

text
PUT pratique-mini/_doc/1
{
  "titre": "Mon premier document"
}

Τι ζητάει το ερώτημα: μέσα στην ντουλάπα pratique-mini, αποθήκευσε μια καρτέλα (_doc) με αριθμό 1 που περιέχει ένα πεδίο titre.

json
{
  "_index": "pratique-mini",
  "_id": "1",
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 1,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 0,
  "_primary_term": 1
}

Τι να προσέξεις: "result": "created" και "_version": 1: πρώτη έκδοση της καρτέλας 1. Ισοδύναμο SQL: INSERT INTO pratique_mini (id, titre) VALUES (1, 'Mon premier document'), μόνο που δεν χρειάστηκε κανένα CREATE TABLE.

Για να κατανοήσεις καλά
  • Το mapping μόλις γεννήθηκε. Πληκτρολόγησε GET pratique-mini/_mapping: το πεδίο titre είναι τώρα δηλωμένο ως τύπος text (για αναζήτηση λέξεων μέσα του) με ένα υποπεδίο titre.keyword (για ταξινόμηση ή φιλτράρισμα στην ακριβή τιμή). Το Elasticsearch το συνήγαγε από την τιμή "Mon premier document", μια αλυσίδα χαρακτήρων.
  • Το 1 του _doc/1, το επέλεξες εσύ. Τα έγγραφα του kit κάνουν το ίδιο (C0001, A00001…). Αν γράψεις POST pratique-mini/_doc χωρίς αριθμό, το Elasticsearch επινοεί ένα _id είκοσι χαρακτήρων· βολικό για αρχεία καταγραφής, ενοχλητικό για μια καρτέλα που θέλεις να βρεις με το χέρι.
  • _shards, _seq_no, _primary_term είναι εσωτερική λογιστική (σε πόσα κομμάτια επιβεβαιώθηκε η εγγραφή, ποιος αριθμός σειράς). Δεν τα χρειάζεσαι σε αυτό το μάθημα.

Βήμα 4 — Ξαναδιάβασμα της καρτέλας

text
GET pratique-mini/_doc/1

Τι ζητάει το ερώτημα: δώσε μου την καρτέλα νούμερο 1 του pratique-mini, απευθείας, χωρίς αναζήτηση.

json
{
  "_index": "pratique-mini",
  "_id": "1",
  "_version": 1,
  "_seq_no": 0,
  "_primary_term": 1,
  "found": true,
  "_source": {
    "titre": "Mon premier document"
  }
}

Τι να προσέξεις: "found": true, και _source, η καρτέλα σου όπως ακριβώς την έγραψες, γράμμα προς γράμμα. Ισοδύναμο SQL: SELECT * FROM pratique_mini WHERE id = 1.

Δοκίμασε μια καρτέλα που δεν υπάρχει: GET pratique-mini/_doc/3.

json
{
  "_index": "pratique-mini",
  "_id": "3",
  "found": false
}

Χωρίς σφάλμα, χωρίς _source: "found": false, σήμα 404 - Not Found. Το Elasticsearch κατάλαβε την ερώτηση· η απάντηση είναι «δεν υπάρχει τίποτα σε αυτόν τον αριθμό».

Βήμα 5 — Προσθήκη τιμών στην καρτέλα

text
POST pratique-mini/_update/1
{
  "doc": {
    "auteur": "Alice",
    "note": 5
  }
}

Τι ζητάει το ερώτημα: ενημέρωσε (_update) την καρτέλα 1 προσθέτοντας αυτά τα δύο πεδία. Ό,τι δεν αναφέρεται (titre) μένει ως έχει.

json
{
  "_index": "pratique-mini",
  "_id": "1",
  "_version": 2,
  "result": "updated",
  "_shards": {
    "total": 1,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 1,
  "_primary_term": 1
}

Τι να προσέξεις: "result": "updated", "_version": 2. Ξαναδιάβασε την καρτέλα με GET pratique-mini/_doc/1:

json
{
  "_index": "pratique-mini",
  "_id": "1",
  "_version": 2,
  "_seq_no": 1,
  "_primary_term": 1,
  "found": true,
  "_source": {
    "titre": "Mon premier document",
    "note": 5,
    "auteur": "Alice"
  }
}

Τρία πεδία. Ο τίτλος είναι ακόμα εκεί. Ισοδύναμο SQL: UPDATE pratique_mini SET auteur = 'Alice', note = 5 WHERE id = 1, με τη διαφορά ότι σε SQL οι στήλες auteur και note θα έπρεπε να υπάρχουν από πριν. Αυτή είναι η απάντηση-παραδοτέο σου: κράτησέ την.

Για να κατανοήσεις καλά
  • Η λέξη doc στο σώμα σημαίνει «να τα πεδία προς συγχώνευση». Χωρίς αυτήν, το _update δεν ξέρει τι να κάνει.
  • Το mapping μεγάλωσε. Το GET pratique-mini/_mapping δείχνει τώρα auteur (text + keyword, όπως το titre) και note τύπου long, έναν ακέραιο. Το Elasticsearch μάντεψε τον τύπο από το 5. Αν είχες γράψει "note": "5" με εισαγωγικά, θα είχε δηλώσει κείμενο, και δεν θα μπορούσες πια να υπολογίσεις μέσο όρο πάνω σε αυτό. Είναι το θέμα του μαθήματος για το mapping, στην ενότητα 2.
  • Το _version μετράει τις εγγραφές σε αυτή την καρτέλα, όχι τις αναγνώσεις: το GET δεν το αυξάνει ποτέ.

Βήμα 6 — Η παγίδα: το PUT αντικαθιστά τα πάντα

Ξαναστείλε ακριβώς το ερώτημα του βήματος 3:

text
PUT pratique-mini/_doc/1
{
  "titre": "Mon premier document"
}
json
{
  "_index": "pratique-mini",
  "_id": "1",
  "_version": 3,
  "result": "updated",
  "_shards": {
    "total": 1,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 3,
  "_primary_term": 1
}

Τι να προσέξεις: "result": "updated" (όχι created: η καρτέλα 1 υπήρχε) και "_version": 3. Μετά ξαναδιάβασέ την:

json
{
  "_index": "pratique-mini",
  "_id": "1",
  "_version": 3,
  "_seq_no": 3,
  "_primary_term": 1,
  "found": true,
  "_source": {
    "titre": "Mon premier document"
  }
}

Τα auteur και note εξαφανίστηκαν. Το PUT _doc/1 δεν τροποποιεί την καρτέλα 1: την αντικαθιστά με ό,τι στέλνεις. Για να συμπληρώσεις χωρίς να χάσεις τίποτα, είναι το POST _update/1 με doc. Κράτησε τον κανόνα με τα δύο ρήματα: το PUT αντικαθιστά, το _update συμπληρώνει. Ξαναβάλε τα δύο πεδία με το ερώτημα του βήματος 5 πριν συνεχίσεις (θα λάβεις _version: 4).

Βήμα 7 — Μια δεύτερη καρτέλα, μέτρημα, αναζήτηση

text
PUT pratique-mini/_doc/2
{
  "titre": "Deuxième document, écrit par Bob",
  "auteur": "Bob",
  "note": 3
}

Απάντηση: "_id": "2", "result": "created", "_version": 1. Μετά μέτρα:

text
GET pratique-mini/_count
json
{
  "count": 2,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  }
}

Ισοδύναμο SQL: SELECT COUNT(*) FROM pratique_mini. Τώρα, δες όλο το περιεχόμενο:

text
GET pratique-mini/_search

Τι ζητάει το ερώτημα: αναζήτησε στο pratique-mini, χωρίς κριτήριο, άρα τα πάντα.

json
{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 1.0,
    "hits": [
      {
        "_index": "pratique-mini",
        "_id": "2",
        "_score": 1.0,
        "_source": {
          "titre": "Deuxième document, écrit par Bob",
          "auteur": "Bob",
          "note": 3
        }
      },
      {
        "_index": "pratique-mini",
        "_id": "1",
        "_score": 1.0,
        "_source": {
          "titre": "Mon premier document",
          "note": 5,
          "auteur": "Alice"
        }
      }
    ]
  }
}

Τι να προσέξεις: hits.total.value: 2 (πόσες καρτέλες ταιριάζουν) μετά hits.hits, η λίστα των καρτελών, καθεμία με το _id και το _source της. Η σειρά των δύο μπορεί να διαφέρει: χωρίς κριτήριο, όλες έχουν το ίδιο _score 1.0. Ισοδύναμο SQL: SELECT * FROM pratique_mini.

Τέλος, αναζήτησε μια λέξη:

text
GET pratique-mini/_search
{
  "query": {
    "match": {
      "titre": "premier"
    }
  }
}

Τι ζητάει το ερώτημα: οι καρτέλες όπου το πεδίο titre περιέχει τη λέξη premier.

json
{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.3788134,
    "hits": [
      {
        "_index": "pratique-mini",
        "_id": "1",
        "_score": 0.3788134,
        "_source": {
          "titre": "Mon premier document",
          "note": 5,
          "auteur": "Alice"
        }
      }
    ]
  }
}

Τι να προσέξεις: μία μόνο καρτέλα, η 1, και ένα _score που δεν είναι πια 1.0: είναι η συνάφεια, «πόσο καλά αυτή η καρτέλα απαντά στην ερώτηση». Η ενότητα 3 είναι αφιερωμένη σε αυτόν τον αριθμό. Κατά προσέγγιση ισοδύναμο SQL: SELECT * FROM pratique_mini WHERE titre LIKE '%premier%', μόνο που το match θα έβρισκε επίσης το Premier με κεφαλαίο, και η ενότητα 2 θα σου εξηγήσει γιατί.

Για να κατανοήσεις καλά
  • Το _count δίνει 0 ή 1 αμέσως μετά από μια εγγραφή; Το Elasticsearch κάνει τις νέες καρτέλες ορατές στην αναζήτηση κάθε δευτερόλεπτο, όχι αμέσως. Ξανατρέξε το _count: είναι ενημερωμένο. Το GET _doc/1, από την άλλη, είναι πάντα άμεσο επειδή δεν αναζητά, πηγαίνει κατευθείαν στον αριθμό. Αν θέλεις να επιβάλεις άμεση ορατότητα σε ένα τεστ: PUT pratique-mini/_doc/2?refresh=true.
  • Το took είναι ο χρόνος της αναζήτησης σε χιλιοστά του δευτερολέπτου. timed_out: false: τελείωσε εντός προθεσμίας.
  • Γιατί GET με σώμα; Είναι μια ιδιαιτερότητα του Elasticsearch: η αναζήτηση είναι ανάγνωση, άρα GET, αλλά η ερώτηση χωράει σε ένα σώμα JSON. Το POST pratique-mini/_search με το ίδιο σώμα δουλεύει επίσης· και τα δύο γίνονται δεκτά.

Βήμα 8 — Διαγραφή μιας καρτέλας, μετά της ντουλάπας

text
DELETE pratique-mini/_doc/2
json
{
  "_index": "pratique-mini",
  "_id": "2",
  "_version": 2,
  "result": "deleted",
  "_shards": {
    "total": 1,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 4,
  "_primary_term": 1
}

Τι να προσέξεις: "result": "deleted". Το GET pratique-mini/_count επιστρέφει 1 (μετά από ένα δευτερόλεπτο). Ισοδύναμο SQL: DELETE FROM pratique_mini WHERE id = 2.

Μετά διάγραψε ολόκληρη την ντουλάπα, μαζί με τις καρτέλες:

text
DELETE pratique-mini
json
{
  "acknowledged": true
}

Απόδειξη ότι δεν υπάρχει πια, GET pratique-mini/_doc/1:

json
{
  "error": {
    "root_cause": [
      {
        "type": "index_not_found_exception",
        "reason": "no such index [pratique-mini]",
        "resource.type": "index_or_alias",
        "resource.id": "pratique-mini",
        "index_uuid": "_na_",
        "index": "pratique-mini"
      }
    ],
    "type": "index_not_found_exception",
    "reason": "no such index [pratique-mini]",
    "resource.type": "index_or_alias",
    "resource.id": "pratique-mini",
    "index_uuid": "_na_",
    "index": "pratique-mini"
  },
  "status": 404
}

Τι να προσέξεις: η διαφορά με το βήμα 4. Καρτέλα απούσα σε ντουλάπα παρούσα: "found": false, χωρίς σφάλμα. Ντουλάπα απούσα: index_not_found_exception, 404. Και οι δύο είναι φυσιολογικές απαντήσεις μιας υπηρεσίας που λειτουργεί. Ισοδύναμο SQL: DROP TABLE pratique_mini.

Τελικός έλεγχος

text
GET _cat/indices/pratique-*?v

Αναμενόμενη απάντηση: μόνο η γραμμή κεφαλίδας. Τίποτα δικό σου δεν παραμένει στο cluster, και το GET _cat/indices/cours,avis,acces?v δείχνει ακόμα 504, 609, 12000.

  • Δημιούργησες το pratique-mini και ξέρεις γιατί ήταν κίτρινο, μετά πράσινο.
  • Αποθήκευσες την καρτέλα 1 με PUT _doc/1 και την ξαναδιάβασες με GET _doc/1.
  • Πρόσθεσες auteur και note με POST _update/1 χωρίς να χάσεις το titre.
  • Είδες το PUT _doc/1 να σβήνει τα δύο πεδία, και ξέρεις να πεις τον κανόνα: το PUT αντικαθιστά, το _update συμπληρώνει.
  • Το _count έδειξε 2, το _search απαρίθμησε τις δύο καρτέλες, το match κράτησε μόνο μία.
  • Διέγραψες την καρτέλα 2 και μετά το index, και το pratique-* είναι άδειο.
  • Κράτησες την απάντηση του GET pratique-mini/_doc/1 με τρία πεδία (βήμα 5) ως παραδοτέο.

Αν κάτι μπλοκάρει

Εμφάνιση συχνών περιπτώσεων
  • 400 με Unexpected character ή was expecting double-quote to start field name → το JSON του σώματος είναι κακοδιατυπωμένο: κάθε όνομα πεδίου και κάθε κείμενο ανάμεσα σε διπλά εισαγωγικά ", ένα κόμμα ανάμεσα στα πεδία, χωρίς κόμμα μετά το τελευταίο. Το Dev Tools υπογραμμίζει το σημείο.
  • 400 με resource_already_exists_exception στο PUT pratique-mini → το index υπάρχει ήδη (ξανάτρεξες το βήμα 1). Συνέχισε στο βήμα 2, ή DELETE pratique-mini για να ξεκινήσεις από το μηδέν.
  • 400 με no handler found for uri → τυπογραφικό λάθος σε μια λέξη με _: _serch, ξεχασμένο _doc/, _udpate. Το Elasticsearch επικυρώνει τη διαδρομή πριν από όλα τα υπόλοιπα.
  • 405 με Incorrect HTTP method for uri [/pratique-mini/_update/1] and method [GET], allowed: [POST] → λάθος ρήμα για αυτή τη διαδρομή. Το μήνυμα λέει το ίδιο ποιο γίνεται δεκτό.
  • 400 με [UpdateRequest] unknown field [titre] → έστειλες τα πεδία απευθείας στο _update, χωρίς να τα τυλίξεις σε "doc": { … }. Πρόσθεσε το περίβλημα.
  • Το _count ή το _search δεν βλέπουν την καρτέλα που μόλις έγραψες → περίμενε ένα δευτερόλεπτο και ξανατρέξε (βλέπε «Για να κατανοήσεις καλά» του βήματος 7). Το GET _doc/1 τη βλέπει αμέσως.
  • "result": "noop" στο _update → οι τιμές που στάλθηκαν ήταν ήδη αυτές της καρτέλας· τίποτα προς αλλαγή, το _version δεν κινήθηκε. Δεν είναι σφάλμα.
  • Το "status": "yellow" επιμένει στο GET _cluster/health μετά το βήμα 2 → ένα άλλο δικό σου index έχει ακόμα rep 1. Το GET _cat/indices?v&health=yellow το εντοπίζει· εφάρμοσέ του το ίδιο _settings, ή διάγραψέ το.
  • Το Dev Tools εμφανίζει «Kibana server is not ready yet» → το Kibana επανεκκινεί ή περιμένει το Elasticsearch· .\labo.ps1 etat ή ./labo.sh etat, μετά η ενότητα 04.