Apa Itu Tax Query di WordPress? Panduan Lengkap untuk Developer
A tax query di WordPress adalah filter terstruktur yang diteruskan ke WP_Query yang mengambil postingan yang cocok dengan term taksonomi tertentu. Alih-alih mengambil setiap postingan dari database, tax query mempersempit kumpulan hasil hanya pada catatan-catatan yang hubungan termnya memenuhi kondisi yang Anda tentukan — baik itu berupa slug kategori tunggal, kombinasi term taksonomi kustom, maupun pola pengecualian multi-taksonomi yang kompleks.
Dalam praktiknya: jika Anda perlu menampilkan hanya postingan yang diberi tag “web-development” yang juga termasuk dalam taksonomi kustom bernama “project-type” dengan term “client-work”, tax query adalah alat yang tepat dan efisien untuk pekerjaan tersebut. Ia beroperasi di level SQL melalui kelas WP_Tax_Query WordPress, menghasilkan klausa JOIN dan WHERE yang dioptimalkan terhadap tabel wp_term_relationships dan wp_term_taxonomy.
Cara Taksonomi dan Term WordPress Disusun
Sebelum menulis satu baris kode query pun, Anda memerlukan gambaran mental yang jelas tentang arsitektur data yang mendasarinya.
Taksonomi adalah sistem klasifikasi. WordPress hadir dengan dua taksonomi global — category dan post_tag — tetapi fungsi register_taxonomy() memungkinkan Anda mendefinisikan taksonomi kustom tanpa batas. Taksonomi pada dasarnya adalah mekanisme pengelompokan bernama.
Term adalah label individual dalam sebuah taksonomi. Dalam taksonomi category, “Technology”, “Lifestyle”, dan “Business” adalah term. Setiap term memiliki tiga pengidentifikasi yang dapat dialamatkan:
term_id— kunci primer integer diwp_termsslug— pengidentifikasi string yang aman untuk URL (misalnya,web-development)name— label tampilan yang mudah dibaca manusia
Hubungan term adalah catatan pivot di wp_term_relationships yang menghubungkan ID objek postingan ke ID taksonomi term. Setiap tax query pada akhirnya diselesaikan menjadi pencarian terhadap tabel ini.
Memahami struktur tiga lapisan ini — taksonomi > term > hubungan term — sangat penting untuk menulis query yang efisien dan mendiagnosis kumpulan hasil yang tidak terduga.
Argumen Inti dari Parameter tax_query
Kunci tax_query menerima array dari satu atau lebih array klausa query, ditambah kunci relation opsional di level teratas. Setiap klausa mendukung argumen berikut:
| Argumen | Tipe | Deskripsi | Nilai Umum |
|---|---|---|---|
| — | — | — | — |
| `taxonomy` | string | Taksonomi yang akan di-query | `category`, `post_tag`, slug kustom |
| `field` | string | Field term mana yang akan dicocokkan | `slug`, `name`, `term_id`, `term_taxonomy_id` |
| `terms` | string / int / array | Nilai term yang akan dicocokkan | `'technology'`, `[4, 7]`, `'web-dev'` |
| `operator` | string | Cara menerapkan pencocokan term | `IN`, `NOT IN`, `AND`, `EXISTS`, `NOT EXISTS` |
| `include_children` | bool | Apakah akan menyertakan term anak (hanya untuk taksonomi hierarkis) | `true` (default), `false` |
| `relation` | string | Penghubung logis level teratas antara beberapa klausa | `AND`, `OR` |
Argumen operator Secara Mendalam
Di sinilah sebagian besar developer membuat kesalahan. Operator-operator tersebut berperilaku sebagai berikut:
IN(default) — mengembalikan postingan yang ditetapkan ke *salah satu* dari term yang ditentukan. Ini adalah pencocokan OR dalam satu klausa.NOT IN— mengecualikan postingan yang ditetapkan ke salah satu dari term yang ditentukan.AND— mengembalikan postingan yang ditetapkan ke *semua* term yang ditentukan secara bersamaan. Gunakan ini ketika sebuah postingan harus memiliki beberapa tag sekaligus.EXISTS— mengembalikan postingan yang memiliki *term apa pun* dalam taksonomi yang ditentukan, terlepas dari term mana. Argumentermsdiabaikan.NOT EXISTS— mengembalikan postingan tanpa penetapan term dalam taksonomi yang ditentukan. Berguna untuk menemukan konten yang tidak dikategorikan atau tidak diberi tag.
Nuansa penting: operator => 'AND' dalam satu klausa memeriksa bahwa satu postingan ditetapkan ke setiap term dalam array terms. Ini berbeda dari menggunakan relation => 'AND' di level teratas, yang menggabungkan klausa-klausa terpisah. Mencampuradukkan keduanya adalah salah satu bug tax query yang paling umum dalam kode WordPress produksi.
Tax Query Dasar: Filter Taksonomi Tunggal
Kasus penggunaan paling sederhana — mengambil semua postingan dalam kategori “Technology”:
$args = array(
'post_type' => 'post',
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'technology',
),
),
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
// Render post content here
}
wp_reset_postdata();
}Selalu panggil wp_reset_postdata() setelah loop WP_Query kustom. Gagal melakukannya akan merusak objek $post global, yang merusak tag template seperti the_title() dan get_the_ID() untuk query berikutnya di halaman yang sama.
Menggabungkan Beberapa Tax Query dengan relation
Kunci relation di level teratas array tax_query mengontrol bagaimana beberapa klausa digabungkan:
$args = array(
'post_type' => 'post',
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'technology',
),
array(
'taxonomy' => 'post_tag',
'field' => 'slug',
'terms' => 'web-development',
),
),
);Ini mengembalikan hanya postingan yang *secara bersamaan* berada dalam kategori “Technology” dan diberi tag “web-development”. Ganti relation dengan 'OR' dan Anda akan mendapatkan postingan yang cocok dengan salah satu kondisi.
Tax Query Bertingkat (WordPress 4.1+)
Untuk logika penyaringan tingkat lanjut, WordPress mendukung array tax_query bertingkat, memungkinkan Anda membangun ekspresi boolean majemuk:
$args = array(
'post_type' => 'product',
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => array( 'laptops', 'desktops' ),
'operator' => 'IN',
),
array(
'relation' => 'OR',
array(
'taxonomy' => 'product_tag',
'field' => 'slug',
'terms' => 'sale',
),
array(
'taxonomy' => 'availability',
'field' => 'slug',
'terms' => 'in-stock',
),
),
),
);Ini mengambil produk dalam “Laptops” atau “Desktops” yang *juga* sedang dijual atau tersedia. Jenis logika bertingkat seperti ini tidak mungkin direplikasi dengan bersih menggunakan kunci relation datar — array bertingkat adalah satu-satunya pendekatan yang benar.
Tipe Postingan Kustom dan Taksonomi Kustom
Tax query menjadi sangat powerful ketika dikombinasikan dengan tipe postingan kustom yang didaftarkan melalui register_post_type() dan taksonomi kustom melalui register_taxonomy(). Pertimbangkan situs portofolio di mana Anda mendaftarkan tipe postingan portfolio dan taksonomi portfolio_type:
// Register custom taxonomy (typically in functions.php or a plugin)
register_taxonomy(
'portfolio_type',
'portfolio',
array(
'label' => 'Portfolio Types',
'hierarchical' => true,
)
);
// Query portfolio items of type "branding"
$args = array(
'post_type' => 'portfolio',
'tax_query' => array(
array(
'taxonomy' => 'portfolio_type',
'field' => 'slug',
'terms' => 'branding',
),
),
);
$query = new WP_Query( $args );Ketika hierarchical adalah true dan include_children tidak secara eksplisit diatur ke false, query secara otomatis menyertakan semua term anak dari “branding”. Ini adalah perilaku yang benar untuk hierarki bergaya kategori, tetapi dapat menghasilkan hasil yang tidak terduga jika Anda memiliki pohon term yang sangat dalam. Atur 'include_children' => false ketika Anda hanya memerlukan pencocokan term yang tepat.
Menggunakan term_id vs. slug vs. name sebagai Nilai field
| Nilai Field | Gunakan Ketika | Perhatian |
|---|---|---|
| — | — | — |
| `slug` | Query yang di-hardcode dalam kode tema/plugin | Slug dapat diubah oleh editor di admin |
| `term_id` | Query yang kritis terhadap performa atau bersifat programatik | ID berbeda antar lingkungan (dev vs. produksi) |
| `name` | Logika yang mudah dibaca manusia, di layer tampilan | Peka huruf besar/kecil; rapuh jika nama diedit |
| `term_taxonomy_id` | Disambiguasi multi-taksonomi | Jarang diperlukan; gunakan hanya ketika ID term bertabrakan antar taksonomi |
Untuk kode produksi, slug umumnya merupakan pilihan paling aman untuk keterbacaan. Namun, jika Anda memigrasikan database antara lingkungan staging dan live, perlu diketahui bahwa nilai term_id akan berbeda. Selalu gunakan slug untuk kode yang portabel.
Pertimbangan Performa dan Jebakan Umum
Dampak Database
Setiap tax query menghasilkan setidaknya satu JOIN tambahan terhadap wp_term_relationships. Dengan beberapa klausa, ini semakin bertambah. Pada situs dengan puluhan ribu postingan, tax query yang tidak terstruktur dengan baik adalah penyebab utama lambatnya pemuatan halaman dan timeout database.
Optimasi utama:
- Gunakan
fields => 'ids'ketika Anda hanya memerlukan ID postingan, bukan objek postingan lengkap. Ini menghindari pemuatan post meta dan data terserialisasi. - Cache hasil dengan Transients API. Tax query pada halaman arsip yang jarang berubah harus di-cache dengan
set_transient()danget_transient(). - Hindari
operator => 'AND'dengan array term yang besar. Setiap term tambahan dalam klausa AND menambahkan subquery. Lakukan benchmark denganEXPLAINdi MySQL sebelum deployment. - Atur
no_found_rows => trueketika Anda tidak memerlukan paginasi. Ini melewati overheadSQL_CALC_FOUND_ROWS.
$args = array(
'post_type' => 'post',
'fields' => 'ids',
'no_found_rows' => true,
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'technology',
),
),
);Jebakan wp_reset_postdata()
Jika Anda menjalankan WP_Query sekunder di dalam loop utama tanpa mereset data postingan, variabel global $post akan menunjuk ke postingan yang salah untuk sisa render halaman. Ini menyebabkan bug yang tidak kentara: judul postingan yang salah di breadcrumb, URL kanonik yang tidak tepat, dan tag Open Graph yang rusak. Selalu lakukan reset.
Melakukan Query pada Term yang Tidak Ada
Jika Anda meneruskan nilai terms yang tidak ada dalam database, WP_Query mengembalikan nol hasil secara diam-diam. Tidak ada error atau peringatan. Selalu validasi keberadaan term dengan term_exists() sebelum membangun tax query dinamis berdasarkan input pengguna atau data eksternal.
$term = term_exists( 'technology', 'category' );
if ( $term !== 0 && $term !== null ) {
// Safe to build the tax query
}Kasus Penggunaan di Dunia Nyata
Halaman Arsip Kustom
Override archive.php atau gunakan pre_get_posts untuk menyuntikkan tax query ke dalam query utama, memfilter arsip untuk menampilkan hanya term tertentu tanpa membuat objek query terpisah:
add_action( 'pre_get_posts', function( $query ) {
if ( ! is_admin() && $query->is_main_query() && is_post_type_archive( 'portfolio' ) ) {
$query->set( 'tax_query', array(
array(
'taxonomy' => 'portfolio_type',
'field' => 'slug',
'terms' => array( 'branding', 'web-design' ),
'operator' => 'IN',
),
) );
}
} );Menggunakan pre_get_posts lebih efisien daripada membuat instansi WP_Query sekunder karena ia memodifikasi query utama sebelum menyentuh database.
Penyaringan Produk E-Commerce
WooCommerce mendaftarkan product_cat dan product_tag sebagai taksonomi WordPress standar, ditambah taksonomi atribut seperti pa_color dan pa_size. Tax query menggerakkan sidebar filter navigasi berlapis. Filter kustom untuk “laptop merah di bawah merek tertentu” akan menggabungkan tiga klausa taksonomi terpisah dengan relation => 'AND'.
Mengecualikan Konten Secara Editorial
Gunakan operator => 'NOT IN' untuk menyembunyikan konten bersponsor atau promosi dari feed editorial:
$args = array(
'post_type' => 'post',
'tax_query' => array(
array(
'taxonomy' => 'post_tag',
'field' => 'slug',
'terms' => array( 'sponsored', 'promoted' ),
'operator' => 'NOT IN',
),
),
);Menemukan Konten yang Tidak Diklasifikasikan
Gunakan operator => 'NOT EXISTS' untuk mengaudit perpustakaan konten Anda untuk postingan yang tidak memiliki penetapan taksonomi yang diperlukan:
$args = array(
'post_type' => 'post',
'tax_query' => array(
array(
'taxonomy' => 'category',
'operator' => 'NOT EXISTS',
),
),
);Ini sangat berharga untuk audit konten pada situs editorial besar di mana postingan mungkin telah diimpor tanpa penetapan taksonomi yang tepat.
Tax Query vs. Meta Query: Memilih Alat yang Tepat
Keputusan arsitektur yang umum dalam pengembangan WordPress adalah apakah akan menyimpan data penyaringan sebagai term taksonomi atau sebagai post meta. Pilihan ini memiliki implikasi performa yang signifikan.
| Kriteria | Tax Query (`tax_query`) | Meta Query (`meta_query`) |
|---|---|---|
| — | — | — |
| Tabel database | `wp_term_relationships` (terindeks) | `wp_postmeta` (kurang dioptimalkan untuk penyaringan) |
| Performa query | Cepat — dirancang untuk pencarian berbasis set | Lebih lambat pada skala besar — struktur EAV |
| Penyaringan berfaset | Native, efisien | Memerlukan solusi alternatif |
| Tipe data | Kosakata terkontrol (term) | Pasangan kunci-nilai arbitrer |
| Kasus penggunaan | Kategorisasi, klasifikasi | Atribut, pengukuran, flag |
| Pengindeksan | Otomatis melalui ID taksonomi term | Memerlukan penyesuaian indeks manual |
Aturan praktis: jika data digunakan untuk penyaringan atau navigasi (warna, kategori, tipe, status), gunakan taksonomi. Jika itu adalah atribut unik per postingan (harga, berat, timestamp publikasi), gunakan post meta. Mencampuradukkan keduanya adalah salah satu penyebab paling umum lambatnya situs WordPress pada skala besar.
Pertimbangan Hosting untuk Situs WordPress yang Menggunakan Query Kompleks
Tax query dengan beberapa klausa, logika bertingkat, atau kumpulan term yang besar menghasilkan SQL yang kompleks. Performa query ini sangat bergantung pada lingkungan server Anda.
Pada paket VPS Hosting, Anda memiliki kendali langsung atas konfigurasi MySQL — Anda dapat menyetel innodb_buffer_pool_size, mengaktifkan cache query (MySQL 5.7 dan sebelumnya), dan menambahkan indeks kustom ke wp_term_relationships jika diperlukan. Lingkungan shared biasanya tidak mengizinkan tingkat penyesuaian database ini.
Jika Anda menjalankan toko WooCommerce dengan lalu lintas tinggi dengan navigasi berlapis yang didukung oleh tax query, Dedicated Server memberi Anda I/O database yang terisolasi, yang menghilangkan masalah noisy-neighbor yang menurunkan waktu respons query pada infrastruktur shared.
Bagi developer yang menginginkan kemudahan panel kontrol sambil mempertahankan akses level server untuk optimasi database, VPS dengan cPanel menyediakan jalan tengah yang praktis — akses MySQL penuh melalui phpMyAdmin bersama antarmuka manajemen yang familiar.
Situs yang sangat bergantung pada endpoint WordPress REST API yang didukung oleh tax query juga harus mempertimbangkan object caching (Redis atau Memcached) di level server, yang dapat dikonfigurasi pada VPS Control Panels yang mendukung layer caching PHP kustom dan sisi server.
Matriks Keputusan dan Daftar Periksa Teknis
Sebelum men-deploy tax query dalam produksi, verifikasi hal-hal berikut:
- Keberadaan term divalidasi — gunakan
term_exists()untuk nilai term yang dikonstruksi secara dinamis wp_reset_postdata()dipanggil — setelah setiap loopWP_Querykustom, tanpa pengecualianinclude_childrendiatur secara eksplisit — jangan mengandalkan default untuk taksonomi hierarkis kecuali penyertaan anak memang disengajafields => 'ids'digunakan — di mana pun objek postingan lengkap tidak diperlukanno_found_rows => truediatur — pada query mana pun yang tidak memerlukan paginasi- Hasil di-cache — gunakan Transients API untuk query pada halaman arsip atau landing page dengan lalu lintas tinggi
pre_get_postslebih diutamakan — daripada instansiWP_Querysekunder untuk modifikasi query utama- Pilihan
operatordikonfirmasi — bedakan antaraIN(term apa pun),AND(semua term), danNOT IN(pengecualian) sebelum menulis klausa - Perbedaan
relationvs.operatorjelas —relationmenghubungkan klausa;operatormengontrol pencocokan dalam sebuah klausa - Array bertingkat digunakan untuk logika majemuk — jangan mencoba mengekspresikan kombinasi AND/OR hanya dengan kunci
relationdatar - Query database dicatat dan ditinjau — gunakan plugin Query Monitor atau
SAVEQUERIESuntuk memeriksa SQL yang dihasilkan sebelum peluncuran
FAQ
Apa perbedaan antara relation => 'AND' dan operator => 'AND' dalam tax query?
relation adalah kunci level teratas yang menghubungkan beberapa klausa tax query satu sama lain — ia menentukan apakah sebuah postingan harus memenuhi semua klausa (AND) atau setidaknya satu (OR). operator adalah kunci per-klausa yang menentukan bagaimana array terms dicocokkan dalam satu klausa — AND mengharuskan postingan memiliki setiap term yang terdaftar ditetapkan secara bersamaan.
Mengapa tax query saya tidak mengembalikan hasil meskipun postingan dan term ada?
Penyebab paling umum adalah: meneruskan nilai terms yang tidak cocok dengan tipe field yang ditentukan (misalnya, meneruskan nama ketika field diatur ke slug), melakukan query pada taksonomi yang tidak didaftarkan untuk tipe postingan, atau menggunakan operator => 'AND' dengan term yang tidak dimiliki oleh satu postingan secara bersamaan. Aktifkan SAVEQUERIES dan periksa SQL mentah untuk mendiagnosis.
Bisakah saya menggunakan tax query di dalam WordPress REST API?
Ya. WP_REST_Posts_Controller REST API menerima tax_query secara tidak langsung melalui parameter query yang terdaftar. Untuk taksonomi kustom, Anda perlu mengatur 'show_in_rest' => true saat mendaftarkan taksonomi. Untuk query multi-klausa yang kompleks, gunakan endpoint REST kustom yang membangun argumen WP_Query di sisi server.
Apakah include_children => true memengaruhi performa?
Ya. Ketika include_children diaktifkan (default untuk taksonomi hierarkis), WordPress menjalankan query tambahan untuk mengambil semua ID term turunan sebelum membangun query utama. Pada taksonomi dengan hierarki yang dalam dan banyak term, pre-query ini menambahkan overhead yang terukur. Atur 'include_children' => false ketika Anda memerlukan pencocokan term yang tepat dan tidak memerlukan pewarisan term anak.
Apakah ada batasan berapa banyak klausa yang dapat dimiliki tax query?
Tidak ada batasan yang di-hardcode dalam inti WordPress, tetapi batasan praktis diberlakukan oleh kedalaman join maksimum MySQL dan ambang kompleksitas query. Lebih dari empat atau lima klausa dalam satu tax query adalah sinyal bahwa model data mungkin perlu dipertimbangkan ulang — baik melalui denormalisasi, indeks pencarian khusus (Elasticsearch, Typesense), atau restrukturisasi hierarki taksonomi untuk mengurangi jumlah klausa.
