Makale Rehberi
Son zamanlarda bir şey üzerinde çalışıyorum.WordPressWeb siteme yüksek performanslı, site genelinde bir arama özelliği eklemek istedim. Uzun araştırmalar sonucunda Meilisearch'ü seçtim ve bunu Scry Search adlı bir eklentiyle birlikte kullandım.
İlk başta her şey sorunsuz ilerledi. Eklentiyi kurdum, yapılandırdım ve indeks otomatik olarak oluşturuldu. Arama hızı inanılmaz derecede yüksekti ve deneyim gerçekten mükemmeldi.
Ama sorun burada ortaya çıkıyor.
Web sitesinde birkaç sıra dışı makale var. Bazıları dahili test amaçlı, bazıları belirli müşteriler için özel açılış sayfaları, diğerleri ise silmek istemediğimiz tamamlanmamış içerikler. Bu makale kimliklerinin arama sonuçlarından tamamen kaybolmasını istiyorum.
Bulunamaması yetmiyor; Meilisearch'ün dizininde bile yer almıyor olması sorun.

Bunun basit olduğunu düşünmüştüm; sadece birkaç kimliği hariç tutmak yeterli. Eklenti dokümantasyonunda ilgili kancalar olmalı; sadece bir filtre ekleyin ve iş tamam.
Sonuç olarak yanılmışım.
Geleneksel dinleme yöntemleri neden başarısız oluyor?
Öncelikle resmi dokümantasyonda belirtilen filtre kancasını denedim. functions.php dosyasına birkaç satır kod ekledim, kaydettim, arka ucu yeniledim ve yeniden indeksledim.
Ardından Meilisearch arka ucunu kontrol ettim.
O makaleler hâlâ orada duruyor.
Şok oldum.
Yanlış kod yazdığımı düşündüm, bu yüzden birkaç kez kontrol ettim ama hiçbir sorun yoktu. Daha sonra eklentinin GitHub Sorunları bölümünü inceledim ve benzer sorunlarla karşılaşan birçok kişi olduğunu gördüm.
Scry Arama eklentisinin, arka planda kaydetme işlemini yavaşlatmamak için eşzamansız bir görev kuyruğu mekanizması kullandığı ortaya çıktı. Bu, arka planda "Makaleyi Kaydet"e tıkladığınızda, verilerin normal tek makale filtrelemesini atlayarak anında özel bir görev tablosuna aktarılabileceği anlamına gelir.
Daha da sinsi olan şey, genel dizini yeniden oluşturmak için arka planda "Gönderileri Dizine Ekle" seçeneğine tıkladığınızda, eklentinin doğrudan alt düzeyde toplu bir veritabanı sorgusu gerçekleştirmesidir. Bu noktada, daha önce eklediğiniz filtre kancası asla çalışma şansı bulamaz.
Başka bir deyişle, geleneksel engelleme yöntemleri yalnızca makaleyi manuel olarak kaydettiğiniz anda devreye girer. Ancak Scry Search'ün senkronizasyon mantığı hayal edebileceğinizden çok daha karmaşıktır.
Çift sigorta önleyici çekirdek kodu
Üzerinde düşündükten sonra, bu meselenin böyle bırakılamayacağını anladım.
Geleneksel kanca yalnızca "tek makale kaydetme" giriş noktasını kontrol ettiğinden, onu diğer yerlerden de engellemenin bir yolunu bulmam gerekiyor.
İki yol belirledim.
İlk sorun ağ üzerinden veri iletimiyle ilgili. İster tek makale senkronizasyonu olsun ister toplu senkronizasyon, nihai verilerin yine de HTTP istekleri aracılığıyla Meilisearch sunucusuna gönderilmesi gerekiyor, değil mi? Bu nedenle, HTTP isteğini göndermeden önce, istek gövdesinde hariç tutulan makalelerin kimlik numaralarının olup olmadığını kontrol etmeliyim. Eğer varsa, isteğin gönderilmesini doğrudan engellemeliyim.
İkinci nokta veritabanı sorgusuyla ilgilidir. Eklenti, toplu indeksleme sırasında makale listesini doğrudan veritabanından aldığı için, veritabanı sorgusunu çalıştırmadan önce bu belirli kimlikleri sorgu sonuçlarından kaldıracağım. Eklentinin bakış açısından, bu makaleler hiç mevcut değil, bu nedenle alınmayacaklar.
İki yol, çifte güvence. Bir yolun engellenememesi durumunda, yedek olarak başka bir yol daha vardır.
Sorunu çözdükten sonra kod yazmaya başladım.
İlk müdahale mekanizması için WordPress'ün yerleşik olanını kullandım.pre_http_requestFiltre. Bu kanca, WordPress herhangi bir HTTP isteği yapmadan önce tetiklenir. Mantığım şu ki, istenen URL'nin içerip içermediğini tespit edecek...meilisearchİstek gövdesinde hariç tutulan makalelerin kimlik numaraları (ID) yer alıyorsa, istek engellenecektir.
Eklentinin hata bildirmesini önlemek için, başarılı bir yanıtı da taklit etmem gerekiyor. Meilisearch için standart yanıt formatı şu şekildedir...{"taskUid":0,"status":"enqueued"}Bunu basitçe geri gönderdim ve eklentinin senkronizasyonun başarılı olduğunu düşünmesini sağladım.
Kullandığım ikinci önleyicipre_get_postsBu kanca, WordPress veritabanı sorgusu çalıştırmadan önce tetiklenir. Mantığım şu: Bir yönetici arka uçta bir işlem gerçekleştirdiğinde veya bir eklenti eşzamansız/eşzamanlı işlemler gerçekleştirdiğinde, hariç tutulan kimlikler birleştirilmelidir...post__not_inParametrelerde.
Yazmayı bitirdikten sonra test ettim.
Öncelikle, arka uca gittim, hariç tutulan makalelerden birini açtım, birkaç küçük değişiklik yaptım ve güncelle düğmesine tıkladım. Herhangi bir hata olmadan başarıyla kaydedildi. Ardından Meilisearch arka ucunu kontrol ettim ve makalenin indeksi değişmemişti; yeni hiçbir şey eklenmemişti.
"Yazıları Dizine Ekle" seçeneğine tekrar tıkladım ve tüm dizini yeniden oluşturdum. Bir süre bekledikten sonra Meilisearch arka ucunu kontrol ettim. Hariç tutulan makaleler hala oradaydı.
İşlem tamamlandı.
Detaylı analiz: Çifte sigorta mekanizması nasıl çalışır?
Dürüst olmak gerekirse, bu süreç bana oldukça ilginç bir şeyi hatırlattı.
Biliyorsunuz, 1880'lerde, Amerika Birleşik Devletleri'nde elektrik yeni yeni yaygınlaşmaya başladığında, birçok fabrika sahibi jeneratör ve elektrik motoru satın almak ve bunları fabrikalarına kurmak için çok para harcadı. Ancak kurulumdan sonra, birçok kişi üretim verimliliğinde önemli bir iyileşme olmadığını fark etti.
为什么?
Çünkü buhar motorunun yerine sadece bir elektrik motoru takılmıştı, ancak fabrikanın genel düzeni, süreçleri ve yönetim yöntemleri değişmeden kalmıştı. Elektrik yeniydi, ancak onu kullanma zihniyeti eskiydi.
Elektrik patlamasından gerçekten fayda sağlayanlar, aslında "elektriğin gerçekte ne anlama geldiğini" anlayan ilk gruptu. Sadece enerji kaynaklarını değiştirmekle kalmadılar; tüm üretim süreçlerini yeniden tasarladılar.
Şu andaAIAynı durum zamanlar için de geçerli. Birçok insan yapay zekayı bir araç olarak kullanıyor, ancak çok azı aslında hangi temel mantığı değiştirdiğini düşünüyor. Araç yeni olabilir, ancak onu kullanmak için kullanılan zihniyet eski kalmış olabilir.
Örneğin, WordPress arama engelleme özelliğini kurarken, eklenti dokümanındaki standart yöntemleri izleseydim muhtemelen çalıştıramazdım. Bunun nedeni, Scry Search'ün senkronizasyon mantığının artık geleneksel "bir makaleyi kaydet, bir makaleyi senkronize et" yaklaşımı olmaması; eşzamansız kuyrukları, toplu işlemeyi ve kendine özgü mekanizmaları olmasıdır.
Gerçek bir atılım gerçekleştirebilmek için önce bu mekanizmanın nasıl çalıştığını anlamanız gerekiyor.
Planın sınırlamaları ve önlemleri
Ancak dürüst olmak gerekirse, bu plan da mükemmel değil.
Önemli bir sınırlaması var: yalnızca gelecekteki senkronizasyonları yönetebiliyor ve Meilisearch'teki mevcut geçmiş kayıtları otomatik olarak silemiyor. Başka bir deyişle, bu makaleleri zaten senkronize ettiyseniz, eski verileri Meilisearch kontrol panelinden veya API komutlarını kullanarak manuel olarak silmeniz gerekiyor.
Bu tek seferlik bir işlem; tamamlandıktan sonra artık endişelenmenize gerek yok. Ancak bunu önceden belirtmem gerekiyor ki, kodu dağıttıktan sonra arama sonuçlarında bu makaleleri hala görüp kodun etkili olmadığını varsaymayın.
Dikkat edilmesi gereken bir diğer nokta ise bu yaklaşımın WordPress'ün temel ağ ve veritabanı mimarisine dayanmasıdır. Scry Search eklentisinin gelecekteki sürümleri bu mimariye göre çalışmaya devam ettiği sürece, bu müdahale mekanizması etkili kalacaktır. Ancak, tamamen farklı bir senkronizasyon mekanizmasına geçilmesi durumunda, yeniden uyarlama gerekebilir.
Dürüst olmak gerekirse, bu pek olası değil. Tüm WordPress ekosistemi bu mimari üzerine kuruludur ve eklentilerin bunu tamamen atlaması neredeyse imkansızdır.
Uygulamaya Yönelik Üç Adımlı Kılavuz
/**
* Scry Search 双保险拦截器:彻底排除指定文章 ID 同步到 Meilisearch
*/
// ==========================================
// 【配置】请在这里填写你想要排除的文章或页面 ID
// ==========================================
define('MEILI_EXCLUDED_IDS', array(1067, 1014, 1474, 34020));
/**
* 保险一:拦截单篇保存/更新时的网络推送 (方案 A 优化版)
* 原理:当 WordPress 发送网络请求时,如果发现是发往 meilisearch 且带有排除的 ID,直接掐断
*/
add_filter('pre_http_request', function($preempt, $parsed_args, $url) {
// 1. 检查是不是发往 Meilisearch 的请求
if (strpos($url, 'meilisearch') !== false && isset($parsed_args['body'])) {
$body_content = $parsed_args['body'];
// 2. 检查请求体里是否包含任何一个被排除的文章 ID
foreach (MEILI_EXCLUDED_IDS as $id) {
// 匹配格式如 "id":1067 或 字符串中的 ID
if (strpos($body_content, (string)$id) !== false) {
// 找到匹配,直接拦截网络请求,并向插件伪造一个标准的成功响应
return array(
'response' => array('code' => 200, 'message' => 'OK'),
'body' => '{"taskUid":0,"status":"enqueued"}'
);
}
}
}
return $preempt;
}, 10, 3);
/**
* 保险二:拦截后台全量索引时的数据库查询 (方案 B)
* 原理:在插件试图从数据库捞取文章列表时,直接将这几个 ID 从查询结果中剔除
*/
add_action('pre_get_posts', function($query) {
// 仅在后台管理员操作,或者插件执行异步同步时生效
if (is_admin() || (defined('DOING_ASYNC') && DOING_ASYNC)) {
// 获取当前查询已经存在的排除 ID(如果有的话)
$current_excluded = $query->get('post__not_in');
if (!is_array($current_excluded)) {
$current_excluded = array();
}
// 将我们的专属排除 ID 合并进去
$query->set('post__not_in', array_merge($current_excluded, MEILI_EXCLUDED_IDS));
}
});
Son olarak, işlem adımlarını özetleyelim.
Öncelikle, kodu functions.php dosyanızın en altına kopyalayın veya Code Snippets eklentisini kullanarak ekleyin. Ardından, en üst kısma...defineDizide, hariç tutmak istediğiniz makalenin veya sayfanın kimliğini girin.
İkinci adım, geçmişe ait indeksleri temizlemektir. Hariç tutulan makaleler için eski indeks verilerini manuel olarak silmek üzere Meilisearch kontrol panelinize giriş yapın veya API komutlarını kullanın.
Üçüncü adım test etme işlemidir. Yönetim paneline gidin ve hariç tutulan makalede küçük değişiklikler yapın, güncelle'ye tıklayın ve ardından Meilisearch yönetim panelini kontrol edin. Yeni bir indeks görünmüyorsa, engelleme işlemi gerçekleşmiştir.
Dürüst olmak gerekirse, bu tür teknik paylaşım makaleleri yazmaktan hep biraz suçluluk duymuşumdur.
Paylaştığım şeyler bazı insanlar için faydalı olabilir, ancak diğerleri için sadece temel işlemler olabilir.
Ancak bu sefer WordPress arama engelleme özelliğini uygulama süreci gerçekten de ufuk açıcıydı. Çoğu zaman karşılaştığımız sorunlar çözüm eksikliğinden değil, düşüncelerimizin mevcut çerçevelerle sınırlı olmasından kaynaklanıyor.
Scry Search eklentisi bir filtreleme kancası sağlıyor ve bu da bize bunun tek seçenek olduğunu düşündürüyor. Ancak WordPress'in tüm mimarisi çok daha fazla olanak sunuyor. Engelleme ağ katmanında ve veritabanı katmanında da gerçekleştirilebilir. Düşünmeye istekli olduğunuz sürece her zaman bir yol vardır.
Bu yüzden bu teknik aletlerle uğraşmaktan keyif alıyorum. Gösteriş yapmak ya da etkileyici görünmeye çalışmakla ilgili değil. Sadece bir problemi tamamen anlamanın verdiği his inanılmaz derecede tatmin edici.
Tıpkı bu sefer olduğu gibi, ilk baştaki kafa karışıklığından, ortadaki düşünmeye ve nihai çözüme kadar tüm süreç bir bulmacayı çözmek gibiydi.
Gizem çözüldü, cevap ortaya çıktı, meğerse her şey çok basitmiş.
Ama o karmaşık süreci yaşamadıysanız, bu basit mutluluğu asla anlayamazsınız.
Buraya kadar okuduysanız ve faydalı bulduysanız lütfen beğenin ve paylaşın. Güncellemeleri ilk öğrenmek istiyorsanız beni takip edebilirsiniz.
Makalemi okuduğunuz için teşekkür ederim. Bir sonraki yazıda görüşmek üzere.
Umut Chen Weiliang Blogu ( https://www.chenweiliang.com/ Burada paylaşılan "WordPress'te Belirli Bir Gönderi Kimliğinin Meilisearch ile Senkronizasyondan Tamamen Hariç Tutulması (Scry Arama Eklentisinin Uygulamada Kullanımı)" başlıklı makale size yardımcı olabilir.
Bu makalenin bağlantısını paylaşmaya hoş geldiniz:https://www.chenweiliang.com/cwl-34343.html
