Artikkelihakemisto
Olen hiljattain työskennellyt WordPress- verkkosivuston parissa ja halusin lisätä siihen tehokkaan koko sivuston kattavan hakukoneen. Pitkän etsinnän jälkeen valitsin Meilisearchin ja yhdistin sen Scry Search -nimiseen lisäosaan.
Aluksi kaikki sujui ongelmitta. Asensin lisäosan, konfiguroin sen, ja indeksi luotiin automaattisesti. Hakunopeus oli salamannopea ja käyttökokemus oli todella erinomainen.
Mutta tässä tulee ongelma.
Verkkosivustolla on useita epätavallisia artikkeleita. Jotkut ovat sisäiseen testaukseen, jotkut ovat tietyille asiakkaille tarkoitettuja laskeutumissivuja ja jotkut ovat keskeneräistä sisältöä, jota emme halua poistaa. Tarvitsen näiden artikkelien tunnisteiden katoavan kokonaan hakutuloksista.
Ei riitä, ettei sitä löydy; sitä ei edes löydy Meilisearchin hakemistosta.

Ajattelin tämän olevan yksinkertaista; kyse on vain muutaman ID:n poissulkemisesta. Lisäosan dokumentaatiossa on oltava vastaavat koukut; lisää vain suodatin ja se on valmis.
Kuten kävi ilmi, olin väärässä.
Miksi perinteiset sieppausmenetelmät epäonnistuvat?
Kokeilin ensin virallisessa dokumentaatiossa mainittua filter hookkia. Lisäsin muutaman rivin koodia functions.php-tiedostoon, tallensin sen, päivitin taustajärjestelmän ja indeksoin sen uudelleen.
Sitten tarkistin Meilisearch-taustajärjestelmän.
Nuo artikkelit ovat siellä edelleen.
Olin ällistynyt.
Luulin kirjoittaneeni väärää koodia, joten tarkistin sen useita kertoja, mutta siinä ei ollut mitään vikaa. Sitten etsin lisäosan GitHub-ongelmia ja huomasin, että useat muutkin olivat kohdanneet samanlaisia ongelmia.
Scry Search -lisäosa käyttää asynkronista tehtäväjonomekanismia välttääkseen taustalla tapahtuvan tallennusprosessin hidastumisen. Tämä tarkoittaa, että kun napsautat taustalla "Tallenna artikkeli", tiedot voidaan välittömästi siirtää mukautettuun tehtävätaulukkoon ohittaen tavallisen yksittäisten artikkelien suodatuksen.
Vielä salakavalampaa on se, että kun napsautat taustalla "Indeksoi viestit" luodaksesi globaalin indeksin uudelleen, lisäosa suorittaa suoraan eräajokyselyn tietokantakyselyn pohjalla. Tässä vaiheessa aiemmin lisäämäsi suodatinkoukku ei koskaan pääse suoriutumaan.
Toisin sanoen perinteiset estomenetelmät tulevat voimaan vasta, kun tallennat artikkelin manuaalisesti. Mutta Scry Searchin synkronointilogiikka on paljon monimutkaisempaa kuin voisit kuvitella.
Tuplavakuutuksen sieppaajan ydinkoodi
Mietittyäni asiaa, tajusin, ettei tätä asiaa voinut jättää näin sikseen.
Koska tavanomainen koukku (hook) hallitsee vain "yksittäisen artikkelin tallennuksen" aloituskohtaa, minun on löydettävä tapa estää se myös muualta.
Olen keksinyt kaksi polkua.
Ensimmäinen ongelma on verkkoyhteyden kautta tapahtuva lähetys. Olipa kyseessä sitten yksittäisten artikkelien synkronointi tai eräsynkronointi, lopulliset tiedot on silti lähetettävä Meilisearch-palvelimelle HTTP-pyyntöjen kautta, eikö niin? Joten ennen HTTP-pyynnön lähettämistä minun tulisi tarkistaa, sisältääkö pyynnön runko näiden poissuljettujen artikkelien tunnukset. Jos näin on, minun pitäisi estää pyynnön lähettäminen suoraan.
Toinen kohta koskee tietokantakyselyä. Koska lisäosa hakee artikkeliluettelon suoraan tietokannasta eräajoindeksoinnin aikana, poistan kyseiset tunnisteet kyselyn tuloksista ennen tietokantakyselyn suorittamista. Lisäosan näkökulmasta näitä artikkeleita ei ole lainkaan olemassa, joten niitä ei haeta.
Kaksi polkua, kaksinkertainen vakuutus. Jos yhtä polkua ei voida estää, on toinen varalla.
Selvitettyäni sen aloin kirjoittaa koodia.
Ensimmäisenä interceptorina käytin WordPressin omaa interceptoria.pre_http_requestSuodatin. Tämä koukku laukeaa ennen kuin WordPress tekee HTTP-pyyntöjä. Logiikkani on, että se havaitsee, sisältääkö pyydetty URL-osoite...meilisearchJos pyynnön runko sisältää poissuljettujen artikkelien tunnukset, pyyntö estetään.
Jotta liitännäinen ei raportoisi virheitä, minun on myös teeskenneltävä onnistunut vastaus. Meilisearchin vakiovastausmuoto on...{"taskUid":0,"status":"enqueued"}Palautin tämän yksinkertaisesti, jolloin lisäosa luulee synkronoinnin onnistuneen.
Toinen käyttämäni torjuntahävittäjäpre_get_postsKoukku. Tämä koukku laukeaa ennen kuin WordPress suorittaa tietokantakyselyn. Logiikkani on, että aina kun ylläpitäjä suorittaa toiminnon taustalla tai kun laajennus suorittaa asynkronisia/synkronisia toimintoja, poissuljetut tunnukset tulisi yhdistää...post__not_inParametreissa.
Kirjoittamisen jälkeen testasin sitä.
Ensin menin taustajärjestelmään, avasin yhden pois jätetyistä artikkeleista, tein muutaman pienen muutoksen ja napsautin päivitä-painiketta. Se tallennettiin onnistuneesti ilman virheitä. Sitten tarkistin Meilisearch-taustajärjestelmän, ja artikkelin hakemisto pysyi muuttumattomana; mitään uutta ei ollut ilmestynyt.
Painoin uudelleen "Indeksoi viestit" ja rakensin koko hakemiston uudelleen. Odotettuani hetken tarkistin Meilisearch-taustajärjestelmän. Poissuljetut artikkelit olivat edelleen siellä.
Se on valmis.
Syvällinen analyysi: Miten kaksoisvakuutusmekanismi toimii?
Rehellisesti sanottuna tämä prosessi muistutti minua eräästä varsin mielenkiintoisesta asiasta.
Tiedättehän, 1880-luvulla, kun sähkö oli vasta yleistymässä Yhdysvalloissa, monet tehtaanomistajat käyttivät paljon rahaa generaattoreiden ja sähkömoottoreiden ostamiseen ja asentamiseen tehtaisiinsa. Asennuksen jälkeen monet ihmiset kuitenkin huomasivat, että tuotannon tehokkuus ei parantunut merkittävästi.
为什么?
Koska he yksinkertaisesti korvasivat höyrykoneen sähkömoottorilla, mutta tehtaan yleinen asettelu, prosessit ja johtamismenetelmät pysyivät ennallaan. Sähkö oli uutta, mutta sen käyttötapa vanhaa.
Ne, jotka todella hyötyivät sähköbuumista, olivat itse asiassa ensimmäinen ryhmä, joka ymmärsi, "mitä sähkö todella tarkoittaa". He eivät vaihtaneet vain virtalähdettään; he suunnittelivat koko tuotantoprosessinsa uudelleen.
Sama pätee tekoälyaikakauteen . Monet ihmiset käyttävät tekoälyä työkaluna, mutta harvat miettivät, mitä taustalla olevaa logiikkaa se muuttaa. Työkalu itsessään on uusi, mutta sen käyttöön käytetty ajattelutapa saattaa jäädä vanhentuneeksi.
Esimerkiksi WordPressin hakunestoa määrittäessäni en luultavasti olisi saanut sitä toimimaan, jos olisin vain noudattanut laajennuksen dokumentaation vakiomenetelmiä. Tämä johtuu siitä, että Scry Searchin synkronointilogiikka ei ole enää perinteinen "tallenna yksi artikkeli, synkronoi yksi artikkeli" -lähestymistapa; siinä on asynkroniset jonot, eräajokäsittely ja omat mekanisminsa.
Sinun täytyy selvittää, miten tämä mekanismi toimii, ennen kuin voit löytää todellisen läpimurron.
Suunnitelman rajoitukset ja varotoimet
Minun on kuitenkin rehellisesti sanottava, että tämäkään suunnitelma ei ole täydellinen.
Sillä on merkittävä rajoitus: se voi hallita vain tulevia synkronointeja eikä voi automaattisesti poistaa olemassa olevia historiallisia tietoja Meilisearchissa. Toisin sanoen, jos olet jo synkronoinut kyseiset artikkelit, sinun on silti poistettava vanhat tiedot manuaalisesti Meilisearchin hallintapaneelissa tai API-komentojen avulla.
Tämä on kertaluonteinen tehtävä; kun se on tehty, sinun ei tarvitse enää huolehtia siitä. Mutta minun on tehtävä tämä selväksi etukäteen, jotta koodin käyttöönoton jälkeen et löydä kyseisiä artikkeleita edelleen hakutuloksista ja oleta, että koodi ei ole tullut voimaan.
Toinen huomionarvoinen seikka on, että tämä lähestymistapa perustuu WordPressin taustalla olevaan verkko- ja tietokanta-arkkitehtuuriin. Niin kauan kuin Scry Search -lisäosan tulevat versiot toimivat tämän arkkitehtuurin pohjalta, tämä sieppari pysyy tehokkaana. Jos se kuitenkin joskus vaihtaa täysin erilaiseen synkronointimekanismiin, uudelleen mukauttaminen voi olla tarpeen.
Rehellisesti sanottuna tämä on kuitenkin epätodennäköistä. Koko WordPress-ekosysteemi on rakennettu tämän arkkitehtuurin päälle, ja laajennusten on käytännössä mahdotonta ohittaa sitä kokonaan.
Kolmivaiheinen käyttöönotto-opas
/**
* 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));
}
});
Lopuksi tiivistetään operaation vaiheet.
Kopioi ensin koodi functions.php-tiedostosi loppuun tai lisää se Code Snippets -laajennuksen avulla. Sitten yläreunaan...defineSyötä taulukkoon sen artikkelin tai sivun tunnus, jonka haluat sulkea pois.
Toinen vaihe on historiallisten indeksien siivoaminen. Kirjaudu Meilisearch-hallintapaneeliisi tai poista vanhat indeksitiedot manuaalisesti pois jätetyistä artikkeleista API-komentojen avulla.
Kolmas vaihe on testaus. Siirry taustajärjestelmään ja tee pienet muutokset poissuljettuun artikkeliin, napsauta päivitä ja tarkista sitten Meilisearch-taustajärjestelmä. Jos uutta indeksiä ei näy, esto on tullut voimaan.
Rehellisesti sanottuna olen aina tuntenut hieman syyllisyyttä kirjoittaessani tällaisia teknisiä jaettavia artikkeleita.
Jakamani asiat voivat olla hyödyllisiä joillekin ihmisille, mutta toisille ne voivat olla vain perustoimintoja.
Mutta WordPress-hakujen estämisen käyttöönottoprosessi tällä kertaa oli todella oivaltava. Usein kohtaamamme ongelmat eivät johdu ratkaisujen puutteesta, vaan pikemminkin siitä, että ajattelumme on rajoittunut olemassa olevien kehysten vuoksi.
Scry Search -lisäosa tarjoaa suodatuskoukun, mikä saa meidät uskomaan, että tämä on ainoa vaihtoehto. Koko WordPressin arkkitehtuuri tarjoaa kuitenkin paljon enemmän mahdollisuuksia. Sieppaus voidaan saavuttaa verkkotasolla, ja se voidaan tehdä myös tietokantatasolla. Niin kauan kuin olet valmis ajattelemaan, ratkaisu löytyy aina.
Siksi nautin näiden teknisten laitteiden näpräämisestä. Kyse ei ole pröystäilystä tai yrityksestä vaikuttaa. Se johtuu yksinkertaisesti siitä, että ongelman täydellinen ymmärtäminen on uskomattoman tyydyttävää.
Aivan kuten tälläkin kertaa, alkuhämmennyksestä keskellä olevaan pohdintaan ja lopulliseen ratkaisuun asti koko prosessi oli kuin palapelin ratkaisemista.
Mysteeri on ratkaistu, vastaus on paljastunut, se osoittautuikin niin yksinkertaiseksi.
Mutta jos et ole käynyt läpi tuota hämmentävää prosessia, et koskaan ymmärrä tätä yksinkertaista iloa.
Nyt kun olet lukenut tähän asti, jos pidit siitä hyödyllisenä, tykkää ja jaa se. Jos haluat saada päivityksiä ensimmäisenä, voit myös seurata minua.
Kiitos, että luit artikkelini. Nähdään taas ensi kerralla.
Toivottavasti Chen Weiliangin blogissa ( https://www.chenweiliang.com/ ) jaetusta artikkelista "Kuinka täysin sulkea tietty viesti-ID pois synkronoinnista Meilisearchin kanssa WordPressissä (Scry Search -laajennus käytännössä)" on sinulle hyötyä.
Voit vapaasti jakaa tämän artikkelin linkin: https://www.chenweiliang.com/cwl-34343.html
