Article Directory
Nedavno sam radio na WordPress web stranici i želio sam dodati visokoučinkovitu tražilicu za cijelu stranicu. Nakon mnogo pretraživanja, odabrao sam Meilisearch i upario ga s dodatkom pod nazivom Scry Search.
U početku je sve išlo glatko. Instalirao sam dodatak, konfigurirao ga i indeks se generirao automatski. Brzina pretraživanja je bila munjevita, a iskustvo je zaista bilo odlično.
Ali evo u čemu je problem.
Na web stranici postoji nekoliko neobičnih članaka. Neki su za interno testiranje, neki su namjenske odredišne stranice za određene klijente, a drugi su nedovršeni sadržaj koji ne želimo izbrisati. Potrebno mi je da ovi ID-ovi članaka potpuno nestanu iz rezultata pretrage.
Nije dovoljno što se ne može pronaći; dovoljno je što se ne može čak ni naći u Meilisearchovom indeksu.

Mislio sam da je ovo jednostavno; samo se radi o izostavljanju nekoliko ID-ova. Dokumentacija dodatka mora imati odgovarajuće hooks-ove; samo dodajte filter i to je to.
Kako se ispostavilo, pogriješio sam.
Zašto konvencionalne metode presretanja ne uspijevaju?
Prvo sam isprobao filter hook spomenut u službenoj dokumentaciji. Dodao sam nekoliko linija koda u functions.php, sačuvao ga, osvježio backend i ponovo ga indeksirao.
Zatim sam provjerio Meilisearch backend.
Ti članci su još uvijek tamo.
Bio sam zapanjen.
Mislio sam da sam napisao pogrešan kod, pa sam ga nekoliko puta provjerio, ali nije bilo ništa loše u njemu. Zatim sam pretražio probleme s dodatkom na GitHubu i otkrio da je nekoliko drugih ljudi imalo slične probleme.
Ispostavilo se da Scry Search dodatak koristi asinhroni mehanizam reda čekanja zadataka kako bi se izbjeglo usporavanje procesa spremanja u pozadini. To znači da kada kliknete na "Sačuvaj članak" u pozadini, podaci se mogu odmah prenijeti u prilagođenu tabelu zadataka, zaobilazeći redovno filtriranje pojedinačnih članaka.
Još podmuklije je to što kada kliknete na "Indeksiraj objave" u pozadini da biste regenerirali globalni indeks, dodatak direktno izvršava grupni upit baze podataka na osnovnom nivou. U ovom trenutku, filter hook koji ste ranije dodali nikada ne dobija priliku da se izvrši.
Drugim riječima, konvencionalne metode blokiranja stupaju na snagu tek u trenutku kada ručno sačuvate članak. Ali logika sinhronizacije Scry Searcha je mnogo složenija nego što biste mogli zamisliti.
Osnovni kod presretača s dvostrukim osiguranjem
Nakon što sam razmislio o tome, shvatio sam da se ova stvar ne može ostaviti ovako.
Budući da konvencionalna kuka kontrolira samo ulaznu tačku "spremanja jednog članka", moram pronaći način da je blokiram i s drugih mjesta.
Smislio sam dva puta.
Prvi problem je prijenos putem mreže. Bilo da se radi o sinhronizaciji pojedinačnih članaka ili grupnoj sinhronizaciji, konačni podaci i dalje moraju biti poslani Meilisearch serveru putem HTTP zahtjeva, zar ne? Dakle, prije slanja HTTP zahtjeva, trebao bih provjeriti da li tijelo zahtjeva sadrži ID-ove tih isključenih članaka. Ako je tako, trebao bih direktno blokirati slanje zahtjeva.
Druga tačka se tiče upita u bazu podataka. Budući da dodatak (plugin) preuzima listu članaka direktno iz baze podataka tokom serijskog indeksiranja, uklonit ću te specifične ID-ove iz rezultata upita prije izvršavanja upita u bazu podataka. Iz perspektive dodatka, ovi članci uopće ne postoje, tako da neće biti preuzeti.
Dva puta, dvostruko osiguranje. Ako se jedan put ne može blokirati, postoji drugi kao rezerva.
Nakon što sam to shvatio, počeo sam pisati kod.
Za prvi presretač koristio sam WordPressov nativni.pre_http_requestFilter. Ovaj hook se aktivira prije nego što WordPress pošalje bilo kakav HTTP zahtjev. Moja logika je da će detektovati da li traženi URL sadrži...meilisearchAko tijelo zahtjeva sadrži ID-ove isključenih članaka, zahtjev će biti blokiran.
Da bih spriječio da dodatak prijavljuje greške, moram i lažirati uspješan odgovor. Standardni format odgovora za Meilisearch je...{"taskUid":0,"status":"enqueued"}Jednostavno sam ovo vratio, zbog čega je dodatak mislio da je sinhronizacija uspješna.
Drugi presretač koji sam koristiopre_get_postsUdica. Ova udica se aktivira prije nego što WordPress izvrši upit u bazi podataka. Moja logika je da kad god administrator izvrši operaciju u pozadini ili kada dodatak izvrši asinhrone/sinhrone operacije, isključeni ID-ovi bi trebali biti spojeni u...post__not_inU parametrima.
Nakon što sam završio s pisanjem, testirao sam ga.
Prvo sam otišao u backend, otvorio jedan od isključenih članaka, napravio nekoliko manjih promjena i kliknuo na ažuriranje. Uspješno je sačuvan bez ikakvih grešaka. Zatim sam provjerio Meilisearch backend i indeks članka je ostao nepromijenjen; ništa novo se nije pojavilo.
Ponovo sam kliknuo na "Indeksiraj objave" i ponovo izgradio cijeli indeks. Nakon što sam čekao neko vrijeme, provjerio sam Meilisearch backend. Ti isključeni članci su još uvijek bili tamo.
Gotovo je.
Detaljna analiza: Kako funkcioniše mehanizam dvostrukog osiguranja?
Iskreno, ovaj proces me podsjetio na nešto prilično zanimljivo.
Znate, 1880-ih, kada je električna energija tek postajala široko rasprostranjena u Sjedinjenim Državama, mnogi vlasnici fabrika trošili su mnogo novca na kupovinu generatora i elektromotora i njihovu ugradnju u svoje fabrike. Međutim, nakon instalacije, mnogi ljudi su otkrili da se efikasnost proizvodnje nije značajno poboljšala.
zasto?
Zato što su jednostavno zamijenili parnu mašinu električnim motorom, ali ukupni raspored, procesi i metode upravljanja fabrikom ostali su nepromijenjeni. Električna energija je bila nova, ali način razmišljanja o njenom korištenju bio je star.
Oni koji su zaista imali koristi od procvata električne energije bili su zapravo prva grupa koja je shvatila "šta električna energija zaista znači". Nisu samo promijenili svoj izvor energije; redizajnirali su cijeli svoj proizvodni proces.
Isto važi i za eru umjetne inteligencije . Mnogi ljudi koriste umjetnu inteligenciju kao alat, ali malo ko razmatra osnovnu logiku koju ona mijenja. Sam alat je nov, ali način razmišljanja koji se koristi za njegovo korištenje može ostati zastario.
Na primjer, kada sam postavljao blokiranje pretrage u WordPressu, vjerovatno ne bih uspio da ga pokrenem da sam samo slijedio standardne metode u dokumentaciji dodatka. To je zato što logika sinhronizacije Scry Searcha više nije tradicionalni pristup "sačuvaj jedan članak, sinhronizuj jedan članak"; ima asinhrone redove čekanja, grupnu obradu i vlastiti skup mehanizama.
Morate shvatiti kako ovaj mehanizam funkcioniše prije nego što možete postići pravi napredak.
Ograničenja i mjere opreza plana
Međutim, moram iskreno reći da ni ovaj plan nije savršen.
Ima značajno ograničenje: može upravljati samo budućim sinhronizacijama i ne može automatski brisati postojeće historijske zapise u Meilisearchu. Drugim riječima, ako ste već sinhronizirali te članke, i dalje morate ručno izbrisati stare podatke u Meilisearch kontrolnoj ploči ili pomoću API naredbi.
Ovo je jednokratni zadatak; kada se završi, više se ne morate brinuti o tome. Ali moram ovo unaprijed pojasniti, kako nakon što implementirate kod, ne biste još uvijek pronašli te članke u rezultatima pretrage i pretpostavili da kod nije stupio na snagu.
Još jedna stvar koju treba napomenuti je da se ovaj pristup oslanja na osnovnu arhitekturu mreže i baze podataka WordPressa. Sve dok buduće verzije dodatka Scry Search nastave raditi na osnovu ove arhitekture, ovaj presretač će ostati efikasan. Međutim, ako ikada pređe na potpuno drugačiji mehanizam sinhronizacije, možda će biti potrebna ponovna adaptacija.
Iskreno, međutim, ovo je malo vjerovatno. Cijeli WordPress ekosistem je izgrađen na ovoj arhitekturi i praktično je nemoguće da je dodaci potpuno zaobiđu.
Vodič za implementaciju u tri koraka
/**
* 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));
}
});
Na kraju, sumirajmo korake operacije.
Prvo, kopirajte kod na samo dno vaše functions.php datoteke ili ga dodajte pomoću dodatka Code Snippets. Zatim, na vrhu...defineU niz unesite ID članka ili stranice koju želite isključiti.
Drugi korak je čišćenje historijskih indeksa. Prijavite se na svoju Meilisearch kontrolnu ploču ili koristite API naredbe za ručno brisanje starih podataka indeksa za isključene članke.
Treći korak je testiranje. Idite na backend i napravite sve manje promjene na isključenom članku, kliknite na ažuriraj, a zatim provjerite Meilisearch backend. Ako se ne pojavi novi indeks, blokiranje je stupilo na snagu.
Iskreno, uvijek sam se osjećao pomalo krivim što pišem ovakve tehničke članke.
Stvari koje dijelim mogu biti korisne nekim ljudima, ali za druge mogu biti samo osnovne operacije.
Ali proces implementacije blokiranja pretrage u WordPressu ovog puta bio je zaista pronicljiv. Često problemi s kojima se susrećemo nisu posljedica nedostatka rješenja, već zato što je naše razmišljanje ograničeno postojećim okvirima.
Scry Search dodatak pruža mogućnost filtriranja, što nas navodi na pomisao da je ovo jedina opcija. Međutim, cijela arhitektura WordPressa nudi daleko više mogućnosti. Presretanje se može postići na mrežnom sloju, a može se izvršiti i na sloju baze podataka. Sve dok ste spremni razmišljati, uvijek postoji način.
Zato uživam petljajući se s ovim tehničkim spravicama. Ne radi se o hvalisanju ili pokušaju da izgledam impresivno. To je jednostavno zato što je osjećaj potpunog razumijevanja problema nevjerovatno zadovoljavajući.
Baš kao i ovaj put, od početne zbunjenosti, preko odraza u sredini, do konačnog rješenja, cijeli proces je bio kao rješavanje zagonetke.
Misterija je riješena, odgovor je otkriven, ispostavilo se da je bilo tako jednostavno.
Ali ako niste prošli kroz taj zbunjujući proces, nikada nećete razumjeti ovu jednostavnu radost.
Sada kada ste pročitali do sada, ako vam je ovo bilo korisno, lajkujte i podijelite. Ako želite prvi primati novosti, možete me i pratiti.
Hvala vam što ste pročitali moj članak. Vidimo se sljedeći put.
Nadam se da će vam članak "Kako potpuno isključiti određeni ID objave iz sinhronizacije sa Meilisearchom u WordPressu (Scry Search dodatak u praksi)" podijeljen na Chen Weiliangovom blogu ( https://www.chenweiliang.com/ ) biti od pomoći.
Slobodno podijelite link ovog članka: https://www.chenweiliang.com/cwl-34343.html
