Lapisan di bawah query: karakter filter, tokenizer, dan token filter; analyzer bawaan, custom analyzer, tes dengan _analyze API, normalizers, n-gram, serta use case autocomplete, case-insensitive search, stemming, dan sinonim.

Di episode 6 kalian memakai query match — tapi pernahkah bertanya mengapa match: "kaos" bisa menemukan dokumen "KAOS POLOS" dengan huruf kapital? Jawabannya bukan di query, melainkan di lapisan yang berjalan sebelum data masuk: text analysis. Inilah yang membuat Elasticsearch jauh lebih pintar daripada pencocokan string biasa. Episode 7 membedah proses analysis: karakter filter, tokenizer, dan token filter; analyzer bawaan; cara mengetes analyzer dengan _analyze API; membuat custom analyzer; normalizers; serta use case nyata — autocomplete, case-insensitive search, stemming, dan sinonim.
Saat sebuah field bertipe text diindeks, teksnya melalui tiga tahap berurutan:
& menjadi "and".char filter : KAOS POLOS Premium
tokenizer : [KAOS] [POLOS] [Premium]
token filter : [kaos] [polos] [premium]Urutannya selalu: char filter → tokenizer → token filter. Kombinasi ketiganya disebut analyzer.
| Analyzer | Perilaku | Contoh token |
|---|---|---|
standard | Bawaan default: pecah kata, lowercase, buang simbol | "Cara-Belajar-ES!" → cara, belajar, es |
simple | Pecah di non-huruf, lowercase, tanpa filter lain | "UPPER-Case!" → upper, case |
whitespace | Pecah hanya di spasi, tanpa lowercase | "KAOS Polos" → KAOS, Polos |
keyword | Seluruh teks jadi satu token (mirip field keyword) | "Kaos Polos" → "Kaos Polos" |
stop | Seperti standard plus membuang stop words | "the quick dog" → quick, dog |
pattern | Pecah berdasarkan regex | khusus untuk format tertentu |
standard adalah default untuk field text. Untuk bahasa tertentu, ada analyzer khusus seperti english yang sekaligus menerapkan stemming — misalnya english akan mengubah "running", "runs" menjadi akar "run".
Sebelum menerapkan analyzer ke mapping, selalu tes dulu lewat endpoint POST /_analyze — ia menunjukkan persis bagaimana teks diproses:
{ "analyzer": "standard", "text": "Kaos POLOS Premium!" }{
"tokens": [
{ "token": "kaos", "start_offset": 0, "end_offset": 4, "type": "<ALPHANUM>", "position": 0 },
{ "token": "polos", "start_offset": 5, "end_offset": 10, "type": "<ALPHANUM>", "position": 1 },
{ "token": "premium", "start_offset": 11, "end_offset": 18, "type": "<ALPHANUM>", "position": 2 }
]
}Perhatikan: ! dihilangkan dan semua token jadi lowercase. Saat nanti hasil pencarian terasa aneh, _analyze adalah alat debugging pertama yang harus kalian pakai.
Analyzer bawaan tidak selalu cocok. Misalnya untuk toko pakaian, kita ingin: menghapus strip ("kaos-polos" jadi "kaos polos"), memecah di whitespace, dan lowercase. Definisi custom analyzer di settings index:
{
"settings": {
"analysis": {
"char_filter": { "strip_dash": { "type": "pattern_replace", "pattern": "-", "replacement": " " } },
"analyzer": {
"produk_analyzer": { "type": "custom", "char_filter": ["strip_dash"], "tokenizer": "whitespace", "filter": ["lowercase"] }
}
}
}
}Lalu pakai analyzer ini di mapping:
{
"mappings": {
"properties": { "name": { "type": "text", "analyzer": "produk_analyzer" } }
}
}Aturan penting: analyzer index (saat data masuk) dan search (saat query) tidak harus sama, tapi untuk konsistensi hasil sebaiknya sama. Kalian bisa menetapkan search_analyzer terpisah jika memang butuh.
Important
Analyzer hanya berlaku untuk field text dan hanya diproses saat indexing. Mengubah analyzer di index yang sudah berisi data tidak mengubah token yang sudah tersimpan — dokumen lama tetap memakai analyzer lama. Ini alasan lain mengapa perubahan mapping/analyzer di production hampir selalu diikuti reindex (episode 13).
Field keyword tidak dianalisis — tapi ada pengecualian: normalizer. Normalizer menerapkan hanya karakter filter dan token filter (tanpa tokenizer), sehingga cocok untuk membuat exact match yang case-insensitive:
{
"settings": {
"analysis": {
"normalizer": {
"lowercase_normalizer": { "type": "custom", "filter": ["lowercase"] }
}
}
},
"mappings": {
"properties": {
"kode_produk": { "type": "keyword", "normalizer": "lowercase_normalizer" }
}
}
}Dengan ini, query term terhadap kode_produk bernilai "KAOS-001" dan "kaos-001" sama-sama cocok — tanpa mengorbankan performa keyword.
N-gram memecah teks menjadi potongan huruf berurutan. edge_ngram hanya mengambil potongan dari awal kata. Ini adalah teknik klasik untuk autocomplete: saat pengguna mengetik "kao", index yang di-build dengan edge n-gram sudah punya token k, ka, kao, kaos — jadi respons datang seketika.
{
"settings": {
"analysis": {
"tokenizer": {
"autocomplete_tokenizer": {
"type": "edge_ngram", "min_gram": 2, "max_gram": 10,
"token_chars": ["letter", "digit"]
}
}
}
}
}Analogi: search_analyzer di sini biasanya tetap standard, sedangkan analyzer saat indexing memakai edge n-gram. Dengan begitu pencarian "kaos" tidak membatasi jumlah huruf, tapi index-nya sudah siap untuk prediksi saat mengetik.
| Use Case | Solusi Analysis |
|---|---|
| Autocomplete search box | Edge n-gram tokenizer di indexing, standard di search |
| Case-insensitive exact match | Normalizer lowercase di field keyword |
| Stemming (cari "makan" temukan "makanan") | Analyzer bahasa, misalnya indonesian atau english |
| Sinonim ("mobil" = "mobil", "car") | Synonym token filter dengan file sinonim |
| HTML yang tidak rapi | HTML strip char filter sebelum tokenizer |
Sinonim dikonfigurasi dengan token filter synonym yang memuat daftar pemetaan:
{
"filter": {
"produk_synonym": {
"type": "synonym",
"synonyms": ["kaos, tshirt, t-shirt", "celana, trousers, pants"]
}
}
}Dengan filter ini, pencarian "tshirt" otomatis ikut mencocokkan dokumen yang memakai kata "kaos" — relevansi naik tanpa mengubah data.
Tip
Analisis teks bersifat sangat spesifik per bahasa dan domain. Jangan asal meng-copy analyzer dari blog lain — selalu tes dengan _analyze memakai data nyata kalian. Satu milidetik di langkah analysis menghemat berjam-jam debugging relevansi di produksi.
Di episode 7 kalian memahami proses analysis: karakter filter, tokenizer, dan token filter yang berjalan berurutan; analyzer bawaan seperti standard dan whitespace; cara mengetes dengan _analyze API; membuat custom analyzer dan normalizers; teknik edge n-gram untuk autocomplete; serta use case stemming dan sinonim.
Inti yang harus dibawa pulang:
_analyze API adalah alat debugging utama untuk masalah relevansi.Sekarang kalian bisa menyesuaikan bagaimana kata diproses. Saatnya menyusun pencarian yang lebih kompleks. Di episode 8 kita masuk ke advanced search: query compound dan boolean — bool dengan must, should, must_not, filter, boosting, constant_score, dan dis_max, plus strategi filter caching dan kapan memakai filter dibanding query. Sampai jumpa!