
# Indexelt szövegkeresés

Az indexelt szövegkeresés a [szövegkeresés](https://greph.inline0.dev/hu/docs/modes/text) gyorsítótárral bemelegített változata. Az első hívás létrehoz egy trigramokat és azonosító-előfordulásokat tartalmazó, lemezen tárolt adattárat; a további hívások ezt használva kihagyják azokat a fájlokat, amelyek nyilvánvalóan nem tartalmazhatják a mintát. Így nagy adattárak ismételt lekérdezéseinél jelentősen csökken a késleltetés, démon vagy figyelőfolyamat bevezetése nélkül.

A bemelegített szövegkeresési felület mostantól a következőket is tartalmazza:

- egyindexes keresés
- ismételt `--index-dir` többindexes keresés
- jegyzékfájl-alapú halmazkeresés
- életciklus-tudatos elavultindex-kezelés
- terveződiagnosztika a `--trace-plan` segítségével

Az index a `greph-index` CLI alatt, valamint a `Greph::buildTextIndex()` / `Greph::searchTextIndexed()` homlokzati metódusokon keresztül érhető el.

## Az index létrehozása

```bash
# Full build at the current directory
./vendor/bin/greph-index build .

# Full build at an explicit root
./vendor/bin/greph-index build path/to/repo

# Use a non-default index directory
./vendor/bin/greph-index build . --index-dir /tmp/greph-index

# Build with an explicit lifecycle policy
./vendor/bin/greph-index build . \
  --lifecycle opportunistic-refresh \
  --auto-refresh-max-files 32 \
  --auto-refresh-max-bytes 1048576
```

Az index alapértelmezés szerint itt tárolódik: `<root>/.greph-index/`.

A sikeres létrehozás egyetlen soros összefoglalót ír ki:

```text
Built index for 2547 files in .greph-index (193428 trigrams, +2547 ~0 -0 =0)
```

A négy számláló a hozzáadott, frissített, törölt és változatlan fájlok számát jelzi. Új felépítéskor a hozzáadott fájlok száma megegyezik a fájlok számával, a többi érték pedig nulla.

## Az index frissítése

```bash
./vendor/bin/greph-index refresh .
```

A `refresh` újra bejárja az indexelt gyökeret, minden fájl hashét kiszámítja, és csak a megváltozott metaadatú bejegyzéseket írja át. A kimenet ugyanazt a négy számlálót használja, így pontosan láthatja, mi változott:

```text
Refreshed index for 2547 files in .greph-index (193428 trigrams, +3 ~7 -1 =2536)
```

Ha a `manual-refresh` használatakor szerkeszti a követett fájlokat, futtassa a `refresh` parancsot. A `opportunistic-refresh` indexeknél a Greph keresés közben automatikusan frissítheti az indexet, ha a módosult fájlok halmaza még elég kicsi.

## Életciklus-profilok

A Greph nem használ démont. Az életciklus-profilok szabályozzák, hogyan viselkedik a bemelegített index a forrásfa változásakor:

- `static`: soha ne ellenőrizze az aktualitást, és ne módosítson automatikusan
- `manual-refresh`: jelezze az elavultságot a `stats` felületen, de keresés közben soha ne frissítsen
- `opportunistic-refresh`: csak akkor frissítsen keresés közben, ha a módosult fájlok száma a beállított küszöb alatt van
- `strict-stale-check`: frissítés helyett utasítsa el az elavult bemelegített kereséseket

Használja a `greph-index stats --dry-refresh` lehetőséget, hogy előre megvizsgálja, mit tenne a bemelegített keresés:

```bash
./vendor/bin/greph-index stats . --dry-refresh
```

## Lekérdezés az indexben

```bash
# Fixed-string search
./vendor/bin/greph-index search -F "function" .

# Case-insensitive whole-word
./vendor/bin/greph-index search -F -i -w "function" .

# Counts
./vendor/bin/greph-index search -F -c "function" .

# Files only
./vendor/bin/greph-index search -F -l "function" .

# Multi-index search
./vendor/bin/greph-index search -F "apply_filters" . \
  --index-dir wordpress/.greph-index \
  --index-dir wp-content/plugins/my-plugin/.greph-index \
  --show-index-origin

# Regex search
./vendor/bin/greph-index search "function\s+\w+" .

# JSON output
./vendor/bin/greph-index search --json -F "function" .

# Planner trace to stderr
./vendor/bin/greph-index search --trace-plan -F "function" .
```

A jelzőkészlet megegyezik a natív szövegkeresésével. A teljes listát lásd a [CLI referenciában](https://greph.inline0.dev/hu/docs/cli#greph-index).

Ha a kért helyen nem létezik az index, a `greph-index search` hibát jelez. Ez a parancs nem áll át automatikusan index nélküli keresésre (az AST-parancsoknál van erre külön bekapcsolható `--fallback scan`, a szövegparancsnál viszont nincs). Előbb építse fel az indexet.

## Elnevezett indexkészletek

Ha ugyanabban a bemelegített elrendezésben keres ismételten, a `--index-dir` jelzők ismételt megadása helyett használjon jegyzékfájlt:

```json
{
  "name": "wordpress-local",
  "indexes": [
    {
      "name": "core-text",
      "root": "wordpress",
      "mode": "text",
      "lifecycle": "static",
      "priority": 100
    },
    {
      "name": "plugin-text",
      "root": "wp-content/plugins/my-plugin",
      "mode": "text",
      "lifecycle": "opportunistic-refresh",
      "max_changed_files": 16,
      "max_changed_bytes": 262144,
      "priority": 200
    }
  ]
}
```

Mentse `.greph-index-set.json` néven, majd:

```bash
./vendor/bin/greph-index set build
./vendor/bin/greph-index set stats --dry-refresh
./vendor/bin/greph-index set search --show-index-origin -F "apply_filters" .
```

## Mit tárol az index

A szövegindex trigramok és azonosító-előfordulások adattára. Minden indexelt fájlból a Greph a következőket nyeri ki:

- **Trigramkészlet**: a fájltartalomban előforduló három bájtos sorozatok halmaza. Durva előszűrőként szolgál a szó szerinti és a reguláris kifejezéses lekérdezéseknél.
- **Azonosító-előfordulások**: a fájlban lévő, azonosítóra emlékeztető tokenek halmaza (`[A-Za-z_][A-Za-z0-9_]*`). Egész szavas kereséseket gyorsít.
- **Életciklus-metaadatok**: tárolt küszöbértékek és az elavultság-ellenőrzés viselkedése.
- **Tartalom-metaadatok**: méret és módosítási idő a frissítési döntésekhez és az elavultság ellenőrzéséhez.

Lekérdezéskor a Greph ugyanilyen mintákat nyer ki a keresési mintából (trigramokat a szó szerinti részkarakterláncokból, azonosítótokent az egész szavas mintákból), metszi az előfordulási halmazokat, és csak a találatokhoz tartozó fájlokat olvassa be újra. A metszetben megmaradó fájlokat ugyanaz a keresőmotor vizsgálja át, mint a natív szöveges módban.

Egyes bemelegített összesítő lekérdezéseket a Greph közvetlenül is megválaszolhat az előfordulási halmazokból:

- egész szavas `-l`
- egész szavas `-L`
- egész szavas `-q`

Így egyáltalán nem kell újra megnyitni a jelölt fájlokat, ha az előfordulási halmazok már bizonyítják a választ.

Ugyanez az elv, mint a ripgrep opcionális előindexelése és a codesearch trigramindexe, de kifejezetten a lemezen tárolt olyan mintákra építve, amelyeket a bemelegített PHP tud a leggyorsabban elérni.

## Terveződiagnosztika

A `--trace-plan` kiírja a bemelegített szövegkereső tervezőjének döntését a `stderr` kimenetre, miközben a normál eredményfolyam változatlan marad.

A nyomkövetés a következőket tartalmazza:

- életciklus-profil
- kiválasztott fájlok száma
- a jelöltek forrása (`full-scan`, `trigram-postings`, `word-postings` vagy `invert-scan`)
- előfordulási halmazokban szereplő kifejezések száma
- jelölt és ellenőrzött fájlok száma
- a közvetlen összesítésre való jogosultság
- a lekérdezési gyorsítótárra való jogosultság és feltöltési döntés

## Mikor használja

Az indexelt mód a megfelelő eszköz, ha:

- Egymás után sokszor keres ugyanabban a tárolóban (CI-feladatok, ügynökciklusok, IDE-integrációk).
- A tároló elég nagy ahhoz, hogy a natív keresés legyen a szűk keresztmetszet.
- A minták szó szerinti részkarakterláncokat vagy azonosítótokeneket tartalmaznak, amelyekre az index előszűrhet.

A natív keresés továbbra is a megfelelő eszköz, ha:

- Kis tárolóban keres, ahol a felépítés költsége meghatározó.
- Egyszeri keresést végez egy olyan útvonalon, amelyre később nem fog újra keresni.
- Egyetlen eseti futtatással szeretné megkapni az összes találatot, és nem akar indexet karbantartani.

A [README](https://github.com/inline0/greph#performance) közzétett benchmarkeredményei szerint a bemelegített indexelt mód a WordPress korpuszon végzett reguláris kifejezéses lekérdezéseknél, valamint a találatok számát, a találatot tartalmazó fájlokat és a találat nélküli fájlokat vizsgáló lekérdezéseknél megelőzi a `rg` és a `grep` módot. Egyszerű szó szerinti lekérdezéseknél gyorsabb a `grep` módnál, de kissé elmarad a `rg` módtól.

## Programozott használat

```php
use Greph\Greph;
use Greph\Text\TextSearchOptions;
use Greph\Index\IndexLifecycleProfile;

// Build once
Greph::buildTextIndex('.', lifecycle: IndexLifecycleProfile::OpportunisticRefresh);

// Refresh after edits
Greph::refreshTextIndex('.');

// Query
$results = Greph::searchTextIndexed(
    'function',
    'src',
    new TextSearchOptions(fixedString: true),
);
```

A `searchTextIndexed` ugyanazt a `TextSearchOptions` fogadja el, mint a natív szövegkeresés, és ugyanolyan alakú `list<TextFileResult>` eredményt ad vissza. Több indexet vagy jegyzékfájlt használó munkafolyamatokhoz használja a `searchTextIndexedMany(...)` és a `searchTextIndexedSet(...)` lehetőséget.
