WordPress’te Vergi Sorgusu Nedir? Eksiksiz Bir Geliştirici Rehberi
WordPress’teki bir vergi sorgusu, belirli taksonomi terimleriyle eşleşen gönderileri alan WP_Query‘ya iletilen yapılandırılmış bir filtredir. Veritabanındaki her gönderiyi çekmek yerine, bir vergi sorgusu sonuç kümesini yalnızca terim ilişkileri tanımladığınız koşulları karşılayan kayıtlarla sınırlandırır — bu, tek bir kategori slug’ı, özel taksonomi terimlerinin bir kombinasyonu veya karmaşık çok taksonomili bir dışlama deseni anlamına gelebilir.
Pratik açıdan: yalnızca “web-development” etiketli ve aynı zamanda “client-work” terimiyle “project-type” adlı özel bir taksonomiye ait gönderileri görüntülemeniz gerekiyorsa, vergi sorgusu bunun için doğru ve performanslı araçtır. wp_term_relationships ve wp_term_taxonomy tablolarına karşı optimize edilmiş JOIN ve WHERE cümleleri üreten WordPress’in WP_Tax_Query sınıfı aracılığıyla SQL düzeyinde çalışır.
WordPress Taksonomileri ve Terimleri Nasıl Yapılandırılır
Tek bir satır sorgu kodu yazmadan önce, temel veri mimarisinin net bir zihinsel modeline ihtiyacınız var.
Taksonomiler sınıflandırma sistemleridir. WordPress iki global taksonomi ile gelir — category ve post_tag — ancak register_taxonomy() fonksiyonu sınırsız sayıda özel taksonomi tanımlamanıza olanak tanır. Taksonomi, özünde adlandırılmış bir gruplama mekanizmasıdır.
Terimler, bir taksonomi içindeki bireysel etiketlerdir. category taksonomisi içinde “Technology”, “Lifestyle” ve “Business” birer terimdir. Her terimin üç adreslenebilir tanımlayıcısı vardır:
term_id—wp_terms‘deki tam sayı birincil anahtarıslug— URL güvenli dize tanımlayıcısı (örn.web-development)name— insan tarafından okunabilir görüntüleme etiketi
Terim ilişkileri, bir gönderinin nesne kimliğini bir terim taksonomi kimliğine bağlayan wp_term_relationships‘deki pivot kayıtlarıdır. Her vergi sorgusu sonuçta bu tabloya karşı bir arama olarak çözümlenir.
Taksonomi > terim > terim ilişkisi şeklindeki bu üç katmanlı yapıyı anlamak, verimli sorgular yazmak ve beklenmedik sonuç kümelerini teşhis etmek için gereklidir.
tax_query Parametresinin Temel Argümanları
tax_query anahtarı, bir veya daha fazla sorgu cümle dizisinden oluşan bir dizi ve isteğe bağlı bir üst düzey relation anahtarı kabul eder. Her cümle aşağıdaki argümanları destekler:
| Argüman | Tür | Açıklama | Yaygın Değerler |
|---|
| — | — | — | — |
|---|
| `taxonomy` | string | Sorgulanacak taksonomi | `category`, `post_tag`, özel slug |
|---|
| `field` | string | Eşleştirilecek terim alanı | `slug`, `name`, `term_id`, `term_taxonomy_id` |
|---|
| `terms` | string / int / array | Eşleştirilecek terim değer(ler)i | `'technology'`, `[4, 7]`, `'web-dev'` |
|---|
| `operator` | string | Terim eşleşmesinin nasıl uygulanacağı | `IN`, `NOT IN`, `AND`, `EXISTS`, `NOT EXISTS` |
|---|
| `include_children` | bool | Alt terimlerin dahil edilip edilmeyeceği (yalnızca hiyerarşik taksonomiler) | `true` (varsayılan), `false` |
|---|
| `relation` | string | Birden fazla cümle arasındaki üst düzey mantıksal bağlayıcı | `AND`, `OR` |
|---|
operator Argümanının Derinlemesine İncelenmesi
Çoğu geliştiricinin hata yaptığı yer burasıdır. Operatörler şu şekilde davranır:
IN(varsayılan) — belirtilen terimlerden *herhangi birine* atanmış gönderileri döndürür. Bu, tek bir cümle içinde VEYA eşleşmesidir.NOT IN— belirtilen terimlerden herhangi birine atanmış gönderileri hariç tutar.AND— belirtilen terimlerin *tümüne* aynı anda atanmış gönderileri döndürür. Bir gönderinin aynı anda birden fazla etiket taşıması gerektiğinde bunu kullanın.EXISTS— hangisi olduğundan bağımsız olarak belirtilen taksonomide *herhangi bir* terime sahip gönderileri döndürür.termsargümanı göz ardı edilir.NOT EXISTS— belirtilen taksonomide terim ataması olmayan gönderileri döndürür. Kategorisiz veya etiketsiz içerikleri bulmak için kullanışlıdır.
Kritik bir nüans: Tek bir cümle içindeki operator => 'AND', bir gönderinin terms dizisindeki her terime atanmış olduğunu kontrol eder. Bu, ayrı cümleleri birleştiren üst düzey relation => 'AND' kullanmaktan farklıdır. Bu ikisini birbirine karıştırmak, üretim WordPress kodundaki en yaygın vergi sorgusu hatalarından biridir.
Temel Vergi Sorgusu: Tek Taksonomi Filtresi
En basit kullanım durumu — “Technology” kategorisindeki tüm gönderileri almak:
$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();
}Özel bir WP_Query döngüsünden sonra her zaman wp_reset_postdata() çağırın. Bunu yapmamak, global $post nesnesini bozar ve aynı sayfadaki sonraki sorgular için the_title() ve get_the_ID() gibi şablon etiketlerini kırar.
relation ile Birden Fazla Vergi Sorgusunu Birleştirme
tax_query dizisinin üst düzeyindeki relation anahtarı, birden fazla cümlenin nasıl birleştirileceğini kontrol eder:
$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',
),
),
);Bu, yalnızca *aynı anda* hem “Technology” kategorisinde hem de “web-development” etiketli gönderileri döndürür. relation‘yi 'OR' olarak değiştirirseniz, her iki koşuldan birini karşılayan gönderileri alırsınız.
İç İçe Vergi Sorguları (WordPress 4.1+)
Gelişmiş filtreleme mantığı için WordPress, bileşik boolean ifadeleri oluşturmanıza olanak tanıyan iç içe tax_query dizilerini destekler:
$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',
),
),
),
);Bu, *aynı zamanda* ya indirimde olan ya da stokta bulunan “Laptops” veya “Desktops” içindeki ürünleri getirir. Bu tür iç içe mantık, düz bir relation anahtarıyla temiz bir şekilde çoğaltılamaz — iç içe diziler tek doğru yaklaşımdır.
Özel Gönderi Türleri ve Özel Taksonomiler
Vergi sorguları, register_post_type() aracılığıyla kaydedilen özel gönderi türleri ve register_taxonomy() aracılığıyla özel taksonomilerle birleştirildiğinde özellikle güçlü hale gelir. Bir portfolio gönderi türü ve bir portfolio_type taksonomisi kaydettiğiniz bir portföy sitesi düşünün:
// 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 );hierarchical true olduğunda ve include_children açıkça false olarak ayarlanmadığında, sorgu otomatik olarak “branding”in tüm alt terimlerini içerir. Bu, kategori tarzı hiyerarşiler için doğru davranıştır, ancak derin iç içe terim ağaçlarınız varsa beklenmedik sonuçlar üretebilir. Yalnızca tam terim eşleşmesine ihtiyaç duyduğunuzda 'include_children' => false ayarlayın.
field Değeri Olarak term_id vs. slug vs. name Kullanımı
| Alan Değeri | Ne Zaman Kullanılır | Dikkat |
|---|
| — | — | — |
|---|
| `slug` | Tema/eklenti kodunda sabit kodlanmış sorgular | Slug’lar yönetici panelindeki editörler tarafından değiştirilebilir |
|---|
| `term_id` | Performans açısından kritik veya programatik sorgular | ID’ler ortamlar arasında farklılık gösterir (geliştirme vs. üretim) |
|---|
| `name` | İnsan tarafından okunabilir, görüntüleme katmanı mantığı | Büyük/küçük harfe duyarlı; isimler düzenlenirse kırılgan |
|---|
| `term_taxonomy_id` | Çok taksonomili belirsizlik giderme | Nadiren gereklidir; yalnızca terim ID’leri taksonomiler arasında çakıştığında kullanın |
|---|
Üretim kodu için slug genellikle okunabilirlik açısından en güvenli seçimdir. Ancak, veritabanlarını hazırlama ve canlı ortam arasında taşıyorsanız, term_id değerlerinin farklılık göstereceğini unutmayın. Taşınabilir kod için her zaman slug kullanın.
Performans Değerlendirmeleri ve Yaygın Tuzaklar
Veritabanı Etkisi
Her vergi sorgusu, wp_term_relationships‘e karşı en az bir ek JOIN üretir. Birden fazla cümleyle bu katlanır. On binlerce gönderiye sahip sitelerde, kötü yapılandırılmış vergi sorguları yavaş sayfa yüklemelerinin ve veritabanı zaman aşımlarının başlıca nedenidir.
Temel optimizasyonlar:
fields => 'ids'kullanın — tam gönderi nesnelerine değil, yalnızca gönderi ID’lerine ihtiyaç duyduğunuzda. Bu, gönderi meta verilerinin ve serileştirilmiş verilerin yüklenmesini önler.- Sonuçları Transients API ile önbelleğe alın. Nadiren değişen arşiv sayfalarındaki vergi sorguları
set_transient()veget_transient()ile önbelleğe alınmalıdır. - Büyük terim dizileriyle
operator => 'AND'kullanmaktan kaçının. AND cümlesindeki her ek terim bir alt sorgu ekler. Dağıtmadan önce MySQL’deEXPLAINile kıyaslama yapın. no_found_rows => trueayarlayın — sayfalamaya ihtiyaç duymadığınızda. Bu,SQL_CALC_FOUND_ROWSyükünü atlar.
$args = array(
'post_type' => 'post',
'fields' => 'ids',
'no_found_rows' => true,
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'technology',
),
),
);wp_reset_postdata() Tuzağı
Birincil bir döngü içinde gönderi verilerini sıfırlamadan ikincil bir WP_Query çalıştırırsanız, global $post değişkeni sayfanın geri kalanı için yanlış gönderiye işaret edecektir. Bu, ince hatalara neden olur: içerik haritalarında yanlış gönderi başlıkları, yanlış kanonik URL’ler ve bozuk Open Graph etiketleri. Her zaman sıfırlayın.
Var Olmayan Terimleri Sorgulamak
Veritabanında bulunmayan bir terms değeri geçerseniz, WP_Query sessizce sıfır sonuç döndürür. Herhangi bir hata veya uyarı yoktur. Kullanıcı girişine veya harici verilere dayalı dinamik vergi sorguları oluşturmadan önce her zaman term_exists() ile terim varlığını doğrulayın.
$term = term_exists( 'technology', 'category' );
if ( $term !== 0 && $term !== null ) {
// Safe to build the tax query
}Gerçek Dünya Kullanım Senaryoları
Özel Arşiv Sayfaları
Ayrı bir sorgu nesnesi oluşturmadan bir arşivi yalnızca belirli terimleri gösterecek şekilde filtrelemek için archive.php‘yi geçersiz kılın veya ana sorguya bir vergi sorgusu enjekte etmek için pre_get_posts kullanın:
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',
),
) );
}
} );pre_get_posts kullanmak, ikincil bir WP_Query örneklemekten daha verimlidir çünkü ana sorguyu veritabanına ulaşmadan önce değiştirir.
E-Ticaret Ürün Filtreleme
WooCommerce, product_cat ve product_tag‘yi standart WordPress taksonomileri olarak kaydeder, ayrıca pa_color ve pa_size gibi özellik taksonomileri de ekler. Vergi sorguları, katmanlı gezinme filtresi kenar çubuğuna güç verir. “Belirli bir markaya ait kırmızı dizüstü bilgisayarlar” için özel bir filtre, relation => 'AND' ile üç ayrı taksonomi cümlesini birleştirir.
İçeriği Editoryal Olarak Hariç Tutmak
Sponsorlu veya tanıtım içeriğini editoryal akışlardan bastırmak için operator => 'NOT IN' kullanın:
$args = array(
'post_type' => 'post',
'tax_query' => array(
array(
'taxonomy' => 'post_tag',
'field' => 'slug',
'terms' => array( 'sponsored', 'promoted' ),
'operator' => 'NOT IN',
),
),
);Sınıflandırılmamış İçeriği Bulmak
Gerekli taksonomi atamalarından yoksun gönderiler için içerik kitaplığınızı denetlemek amacıyla operator => 'NOT EXISTS' kullanın:
$args = array(
'post_type' => 'post',
'tax_query' => array(
array(
'taxonomy' => 'category',
'operator' => 'NOT EXISTS',
),
),
);Bu, gönderilerin uygun taksonomi ataması olmadan içe aktarılmış olabileceği büyük editoryal sitelerdeki içerik denetimleri için son derece değerlidir.
Vergi Sorgusu vs. Meta Sorgusu: Doğru Aracı Seçmek
WordPress geliştirmede yaygın bir mimari karar, filtreleme verilerinin bir taksonomi terimi olarak mı yoksa gönderi meta verisi olarak mı depolanacağıdır. Bu seçimin önemli performans etkileri vardır.
| Kriter | Vergi Sorgusu (`tax_query`) | Meta Sorgusu (`meta_query`) |
|---|
| — | — | — |
|---|
| Veritabanı tablosu | `wp_term_relationships` (indekslenmiş) | `wp_postmeta` (filtreleme için daha az optimize edilmiş) |
|---|
| Sorgu performansı | Hızlı — küme tabanlı aramalar için tasarlanmış | Ölçekte daha yavaş — EAV yapısı |
|---|
| Çok yönlü filtreleme | Yerel, verimli | Geçici çözümler gerektirir |
|---|
| Veri türü | Kontrollü kelime dağarcığı (terimler) | Rastgele anahtar-değer çiftleri |
|---|
| Kullanım senaryosu | Kategorilendirme, sınıflandırma | Özellikler, ölçümler, bayraklar |
|---|
| İndeksleme | Terim taksonomi ID’leri aracılığıyla otomatik | Manuel indeks ayarlaması gerektirir |
|---|
Temel kural: veriler filtreleme veya gezinme için kullanılıyorsa (renk, kategori, tür, durum), taksonomi kullanın. Gönderi başına benzersiz bir özellikse (fiyat, ağırlık, yayın zaman damgası), gönderi meta verisi kullanın. Bunları karıştırmak, ölçekte yavaş WordPress sitelerinin en yaygın nedenlerinden biridir.
Karmaşık Sorgular Kullanan WordPress Siteleri için Barındırma Değerlendirmeleri
Birden fazla cümle, iç içe mantık veya büyük terim kümeleri içeren vergi sorguları karmaşık SQL üretir. Bu sorguların performansı, sunucu ortamınıza büyük ölçüde bağlıdır.
Bir VPS Hosting planında, MySQL yapılandırması üzerinde doğrudan kontrole sahipsiniz — innodb_buffer_pool_size‘yi ayarlayabilir, sorgu önbelleğini etkinleştirebilir (MySQL 5.7 ve öncesi) ve gerekirse wp_term_relationships‘ye özel indeksler ekleyebilirsiniz. Paylaşımlı ortamlar genellikle bu düzeyde veritabanı ayarlamasına izin vermez.
Vergi sorguları tarafından desteklenen katmanlı gezinmeye sahip yüksek trafikli bir WooCommerce mağazası işletiyorsanız, bir Dedicated Server size izole veritabanı G/Ç’si sağlar; bu da paylaşımlı altyapıda sorgu yanıt sürelerini düşüren gürültülü komşu sorununu ortadan kaldırır.
Veritabanı optimizasyonu için sunucu düzeyinde erişimi korurken bir kontrol panelinin rahatlığını isteyen geliştiriciler için, cPanel ile VPS pratik bir orta yol sunar — tanıdık bir yönetim arayüzünün yanı sıra phpMyAdmin aracılığıyla tam MySQL erişimi.
Vergi sorgularıyla desteklenen WordPress REST API uç noktalarına yoğun biçimde dayanan siteler, özel PHP ve sunucu tarafı önbellekleme katmanlarını destekleyen VPS Kontrol Panelleri‘nde yapılandırılabilen sunucu düzeyinde nesne önbelleklemesini (Redis veya Memcached) de göz önünde bulundurmalıdır.
Karar Matrisi ve Teknik Kontrol Listesi
Üretimde bir vergi sorgusu dağıtmadan önce aşağıdakileri doğrulayın:
- Terim varlığı doğrulandı — dinamik olarak oluşturulan terim değerleri için
term_exists()kullanın wp_reset_postdata()çağrıldı — istisnasız her özelWP_Querydöngüsünden sonrainclude_childrenaçıkça ayarlandı — alt dahil etme kasıtlı olmadıkça hiyerarşik taksonomiler için varsayılana güvenmeyinfields => 'ids'kullanıldı — tam gönderi nesnelerinin gerekli olmadığı her yerdeno_found_rows => trueayarlandı — sayfalama gerektirmeyen herhangi bir sorguda- Sonuçlar önbelleğe alındı — yüksek trafikli arşiv veya açılış sayfalarındaki sorgular için Transients API kullanın
pre_get_poststercih edildi — ana sorgu değişiklikleri için ikincilWP_Queryörnekleri yerineoperatorseçimi onaylandı — cümleyi yazmadan önceIN(herhangi bir terim),AND(tüm terimler) veNOT IN(dışlama) arasındaki farkı ayırt edinrelationvs.operatorayrımı netleştirildi —relationcümleleri birbirine bağlar;operatorbir cümle içindeki eşleşmeyi kontrol eder- Bileşik mantık için iç içe diziler kullanıldı — AND/OR kombinasyonlarını yalnızca düz bir
relationanahtarıyla ifade etmeye çalışmayın - Veritabanı sorgusu kaydedildi ve incelendi — başlatmadan önce oluşturulan SQL’i incelemek için Query Monitor eklentisini veya
SAVEQUERIES‘yi kullanın
SSS
Bir vergi sorgusunda relation => 'AND' ile operator => 'AND' arasındaki fark nedir?
relation, birden fazla vergi sorgusu cümlesini birbirine bağlayan üst düzey bir anahtardır — bir gönderinin tüm cümleleri (AND) mi yoksa en az birini (OR) mi karşılaması gerektiğini belirler. operator ise tek bir cümle içinde terms dizisinin nasıl eşleştirileceğini belirleyen cümle başına bir anahtardır — AND, gönderinin listelenen her terimin aynı anda atanmış olmasını gerektirir.
Gönderiler ve terimler mevcut olmasına rağmen vergi sorgum neden sonuç döndürmüyor?
En yaygın nedenler şunlardır: belirtilen field türüyle eşleşmeyen bir terms değeri geçirmek (örn. field slug olarak ayarlandığında bir isim geçirmek), gönderi türü için kayıtlı olmayan bir taksonomiyi sorgulamak veya hiçbir gönderinin aynı anda sahip olmadığı terimlerle operator => 'AND' kullanmak. Teşhis için SAVEQUERIES‘yi etkinleştirin ve ham SQL’i inceleyin.
WordPress REST API içinde bir vergi sorgusu kullanabilir miyim?
Evet. REST API’nin WP_REST_Posts_Controller‘si, kayıtlı sorgu parametreleri aracılığıyla dolaylı olarak tax_query‘yi kabul eder. Özel taksonomiler için, taksonomiyi kaydederken 'show_in_rest' => true ayarlamanız gerekir. Karmaşık çok cümleli sorgular için, WP_Query argümanlarını sunucu tarafında oluşturan özel bir REST uç noktası kullanın.
include_children => true performansı etkiler mi?
Evet. include_children etkinleştirildiğinde (hiyerarşik taksonomiler için varsayılan), WordPress ana sorguyu oluşturmadan önce tüm alt terim ID’lerini almak için ek bir sorgu çalıştırır. Derin hiyerarşilere ve çok sayıda terime sahip taksonomilerde, bu ön sorgu ölçülebilir ek yük ekler. Alt terim mirasına ihtiyaç duymadığınızda ve tam terim eşleşmesine ihtiyaç duyduğunuzda 'include_children' => false ayarlayın.
Bir vergi sorgusunun kaç cümlesi olabileceğine dair bir sınır var mı?
WordPress çekirdeğinde sabit kodlanmış bir sınır yoktur, ancak pratik sınırlar MySQL’in maksimum birleştirme derinliği ve sorgu karmaşıklığı eşikleri tarafından belirlenir. Tek bir vergi sorgusunda dörtten veya beşten fazla cümle, veri modelinin yeniden değerlendirilmesi gerekebileceğinin bir işaretidir — bu, normalleştirmeyi kaldırma, özel bir arama indeksi (Elasticsearch, Typesense) veya cümle sayısını azaltmak için taksonomi hiyerarşisini yeniden yapılandırma yoluyla yapılabilir.
