Indexované vyhľadávanie textu
Indexované vyhľadávanie textu je verzia vyhľadávania textu s prednačítanou cache. Prvé volanie vytvorí úložisko trigramov a výskytov identifikátorov na disku; ďalšie volania ho používajú na preskočenie súborov, ktoré zjavne nemôžu obsahovať vzor. Výsledkom je výrazne nižšia latencia pri opakovaných vyhľadávaniach vo veľkých repozitároch bez potreby démona alebo procesu sledovania zmien.
Prednačítané textové vyhľadávanie teraz zahŕňa:
- vyhľadávanie v jednom indexe
- opakované vyhľadávanie vo viacerých indexoch
--index-dir - vyhľadávanie v množinách podložených manifestom
- spracovanie zastaraných údajov zohľadňujúce životný cyklus
- diagnostiku plánovača cez
--trace-plan
Index je štandardne dostupný cez greph-index CLI a metódy fasády Greph::buildTextIndex() / Greph::searchTextIndexed().
Zostavenie indexu
# 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
Index sa štandardne ukladá do <root>/.greph-index/.
Úspešné zostavenie vypíše súhrn v jednom riadku:
Built index for 2547 files in .greph-index (193428 trigrams, +2547 ~0 -0 =0)
Štyri počítadlá uvádzajú počet pridaných, aktualizovaných, odstránených a nezmenených súborov. Pri novom zostavení sa počítadlo pridaných rovná počtu súborov a všetky ostatné majú hodnotu nula.
Obnovenie indexu
./vendor/bin/greph-index refresh .
refresh znova prejde indexovaný koreňový adresár, vypočíta hash každého súboru a prepíše iba položky, ktorých metadáta sa zmenili. Výstup používa tie isté štyri počítadlá, aby ste presne videli, čo sa zmenilo:
Refreshed index for 2547 files in .greph-index (193428 trigrams, +3 ~7 -1 =2536)
Po úprave sledovaných súborov spustite refresh, ak používate manual-refresh. Pri indexoch opportunistic-refresh môže Greph automaticky obnoviť index počas vyhľadávania, ak je množina zmien stále dostatočne malá.
Profily životného cyklu
Greph funguje bez démona. Profily životného cyklu určujú, ako sa prednačítaný index správa pri zmene zdrojového stromu:
static: nikdy automaticky nekontrolovať aktuálnosť ani nič nemeniťmanual-refresh: uvádzať zastarané informácie vstats, ale počas vyhľadávania nikdy neobnovovaťopportunistic-refresh: obnovovať počas vyhľadávania iba vtedy, keď je množina zmien pod nakonfigurovanými limitmistrict-stale-check: odmietnuť zastarané vyhľadávania v prednačítanom indexe namiesto obnovovania
Pomocou greph-index stats --dry-refresh si pred spustením vyhľadávania prezrite, čo by prednačítané vyhľadávanie vykonalo:
./vendor/bin/greph-index stats . --dry-refresh
Vyhľadávanie v indexe
# 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" .
Množina príznakov je rovnaká ako pri natívnom vyhľadávaní textu. Úplný zoznam nájdete v CLIreferenčnej príručke.
Ak index na požadovanom mieste neexistuje, greph-index search vyvolá chybu. Tento príkaz automaticky neprechádza na prehľadávanie bez indexu (príkazy AST majú voliteľný parameter --fallback scan, textový príkaz ho však nemá). Najprv zostavte index.
Pomenované množiny indexov
Ak opakovane vyhľadávate v rovnakom prednačítanom usporiadaní, použite manifest namiesto opakovania príznakov --index-dir:
{
"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
}
]
}
Uložte ho ako .greph-index-set.json a potom:
./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" .
Čo index ukladá
Textový index je úložisko trigramov a výskytov identifikátorov. Pre každý indexovaný súbor Greph získava:
- Množina trigramov: množina trojíc bajtov v obsahu súboru. Používa sa ako hrubý predbežný filter pre doslovné vyhľadávanie aj vyhľadávanie regulárnymi výrazmi.
- Výskyty identifikátorov: množina tokenov v tvare identifikátorov (
[A-Za-z_][A-Za-z0-9_]*) v súbore. Používa sa na zrýchlenie vyhľadávania celých slov. - Metadáta životného cyklu: uložené limity a správanie pri kontrole zastaranosti.
- Metadáta obsahu: veľkosť a čas poslednej úpravy na rozhodovanie o obnovení a kontrolu zastaranosti.
Po prijatí dopytu Greph získa rovnaké tvary zo vzoru (trigramy z doslovných podreťazcov, tokeny identifikátorov zo vzorov celých slov), pretne množiny výskytov a znova načíta iba zodpovedajúce súbory. Súbory, ktoré prejdú prienikom, sa vyhľadajú rovnakým nástrojom ako v natívnom textovom režime.
Pri niektorých súhrnných dopytoch v prednačítanom režime môže Greph odpovedať priamo z výskytov:
- celé slovo
-l - celé slovo
-L - celé slovo
-q
Vďaka tomu sa kandidátne súbory vôbec nemusia znova otvárať, ak už výskyty dokazujú odpoveď.
Je to rovnaký princíp ako voliteľné predindexovanie v ripgrep a trigramový index v codesearch, zostavený však špeciálne pre tvary na disku, ktoré prednačítaný PHP dokáže spracovať najrýchlejšie.
Diagnostika plánovača
--trace-plan odovzdáva rozhodnutie plánovača prednačítaného textového vyhľadávania do stderr a pritom nemení bežný prúd výsledkov.
Záznam obsahuje:
- profil životného cyklu
- počet vybraných súborov
- zdroj kandidátov (
full-scan,trigram-postings,word-postingsaleboinvert-scan) - počet výrazov vo výskytoch
- počet kandidátnych a overených súborov
- oprávnenosť na priame vytvorenie súhrnu
- oprávnenosť použitia cache dopytov a rozhodnutie o jej naplnení
Kedy ho použiť
Indexovaný režim je vhodný, keď:
- Vyhľadávate v tom istom repozitári opakovane (úlohy CI, cykly agentov, integrácie IDE).
- Repozitár je natoľko veľký, že úzkym miestom je natívne prehľadávanie.
- Vzory obsahujú doslovné podreťazce alebo tokeny identifikátorov, podľa ktorých môže index filtrovať.
Natívne prehľadávanie je stále vhodné, keď:
- Vyhľadávate v malom repozitári, kde prevažujú náklady na zostavenie indexu.
- Vyhľadávate v jednorazovej ceste, ktorú už znova prehľadávať nebudete.
- Potrebujete všetky zhody pri jednom príležitostnom spustení a nechcete udržiavať index.
Zverejnené výsledky porovnávacích testov v README ukazujú, že prednačítaný indexovaný režim je pri dopytoch s regulárnymi výrazmi a pri dopytoch na počet, súbory so zhodami a súbory bez zhôd v korpuse WordPress rýchlejší než rg aj grep. Pri dopytoch s jednoduchým doslovným textom je rýchlejší než grep, ale zostáva mierne pomalší než rg.
Programové použitie
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),
);
searchTextIndexed prijíma rovnaké TextSearchOptions ako natívne vyhľadávanie textu a vracia výsledok v rovnakom tvare list<TextFileResult>. Pri práci s viacerými indexmi alebo manifestom použite searchTextIndexedMany(...) a searchTextIndexedSet(...).