15%

Tüm Hosting Hizmetlerinde %15 indirim

Becerilerini test et ve herhangi bir hosting planında İndirim kazan

Kodu kullanın:

Skills
Başlayın
21.10.2024

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_idwp_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ümanTürAçıklamaYaygın Değerler
`taxonomy`stringSorgulanacak taksonomi`category`, `post_tag`, özel slug
`field`stringEşleştirilecek terim alanı`slug`, `name`, `term_id`, `term_taxonomy_id`
`terms`string / int / arrayEşleştirilecek terim değer(ler)i`'technology'`, `[4, 7]`, `'web-dev'`
`operator`stringTerim eşleşmesinin nasıl uygulanacağı`IN`, `NOT IN`, `AND`, `EXISTS`, `NOT EXISTS`
`include_children`boolAlt terimlerin dahil edilip edilmeyeceği (yalnızca hiyerarşik taksonomiler)`true` (varsayılan), `false`
`relation`stringBirden 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. terms argü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ğeriNe Zaman KullanılırDikkat
`slug`Tema/eklenti kodunda sabit kodlanmış sorgularSlug’lar yönetici panelindeki editörler tarafından değiştirilebilir
`term_id`Performans açısından kritik veya programatik sorgularID’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 gidermeNadiren 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() ve get_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’de EXPLAIN ile kıyaslama yapın.
  • no_found_rows => true ayarlayın — sayfalamaya ihtiyaç duymadığınızda. Bu, SQL_CALC_FOUND_ROWS yü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.

KriterVergi 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ü filtrelemeYerel, verimliGeçici çözümler gerektirir
Veri türüKontrollü kelime dağarcığı (terimler)Rastgele anahtar-değer çiftleri
Kullanım senaryosuKategorilendirme, sınıflandırmaÖzellikler, ölçümler, bayraklar
İndekslemeTerim taksonomi ID’leri aracılığıyla otomatikManuel 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 özel WP_Query döngüsünden sonra
  • include_children açıkça ayarlandı — alt dahil etme kasıtlı olmadıkça hiyerarşik taksonomiler için varsayılana güvenmeyin
  • fields => 'ids' kullanıldı — tam gönderi nesnelerinin gerekli olmadığı her yerde
  • no_found_rows => true ayarlandı — 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_posts tercih edildi — ana sorgu değişiklikleri için ikincil WP_Query örnekleri yerine
  • operator seçimi onaylandı — cümleyi yazmadan önce IN (herhangi bir terim), AND (tüm terimler) ve NOT IN (dışlama) arasındaki farkı ayırt edin
  • relation vs. operator ayrımı netleştirildirelation cümleleri birbirine bağlar; operator bir 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 relation anahtarı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.

15%

Tüm Hosting Hizmetlerinde %15 indirim

Becerilerini test et ve herhangi bir hosting planında İndirim kazan

Kodu kullanın:

Skills
Başlayın