Rakstu katalogs
Nesen strādāju pie WordPress vietnes un vēlējos pievienot augstas veiktspējas meklētājprogrammu visai vietnei. Pēc ilgiem meklējumiem izvēlējos Meilisearch un savienoju to ar spraudni ar nosaukumu Scry Search.
Sākumā viss noritēja gludi. Es instalēju spraudni, konfigurēju to, un indekss tika ģenerēts automātiski. Meklēšanas ātrums bija zibensātrs, un pieredze patiešām bija lieliska.
Bet te nu rodas problēma.
Tīmekļa vietnē ir vairāki neparasti raksti. Daži ir paredzēti iekšējai testēšanai, daži ir īpaši izstrādātas mērķlapas konkrētiem klientiem, bet citi ir nepabeigts saturs, ko nevēlamies dzēst. Man ir nepieciešams, lai šo rakstu ID pilnībā pazustu no meklēšanas rezultātiem.
Nepietiek ar to, ka to nevar atrast; tas pat nevar būt Meilisearch indeksā.

Es domāju, ka tas ir vienkārši; atliek tikai izslēgt dažus ID. Spraudņa dokumentācijā jābūt atbilstošiem āķiem; vienkārši pievienojiet filtru, un viss.
Kā izrādījās, es kļūdījos.
Kāpēc tradicionālās pārtveršanas metodes neizdodas?
Vispirms izmēģināju filtra āķi, kas minēts oficiālajā dokumentācijā. Pievienoju dažas koda rindiņas failam functions.php, saglabāju to, atsvaidzināju aizmugursistēmu un atkārtoti to indeksēju.
Tad es pārbaudīju Meilisearch aizmugursistēmu.
Tie raksti joprojām tur ir.
Es biju apstulbis.
Man šķita, ka esmu uzrakstījis nepareizu kodu, tāpēc vairākas reizes to pārbaudīju, bet tur nebija nekā slikta. Pēc tam es meklēju spraudņa GitHub problēmu sadaļā un atklāju, ka vairāki citi cilvēki ir saskārušies ar līdzīgām problēmām.
Izrādās, ka Scry Search spraudnis izmanto asinhronu uzdevumu rindas mehānismu, lai nepalēninātu fona saglabāšanas procesu. Tas nozīmē, ka, fonā noklikšķinot uz “Saglabāt rakstu”, dati var tikt nekavējoties ievietoti pielāgotā uzdevumu tabulā, apejot parasto atsevišķu rakstu filtrēšanu.
Vēl viltīgāks ir tas, ka, noklikšķinot uz "Indeksēt ierakstus" fonā, lai atjaunotu globālo indeksu, spraudnis tieši veic pakešveida datubāzes vaicājumu pamatā esošajā līmenī. Šajā brīdī iepriekš pievienotajam filtra āķim nekad nav iespējas izpildīties.
Citiem vārdiem sakot, tradicionālās bloķēšanas metodes stājas spēkā tikai brīdī, kad manuāli saglabājat rakstu. Taču Scry Search sinhronizācijas loģika ir daudz sarežģītāka, nekā jūs varētu iedomāties.
Divkāršās apdrošināšanas pārtvērēja pamatkods
Pēc pārdomām sapratu, ka šo lietu nevar atstāt tā, kā vajag.
Tā kā parastais āķis kontrolē tikai "viena raksta saglabāšanas" ieejas punktu, man jāatrod veids, kā to bloķēt arī no citām vietām.
Esmu izdomājis divus ceļus.
Pirmā problēma ir tīkla pārraides puse. Neatkarīgi no tā, vai tā ir atsevišķu rakstu sinhronizācija vai partiju sinhronizācija, galīgie dati joprojām ir jānosūta uz Meilisearch serveri, izmantojot HTTP pieprasījumus, vai ne? Tātad, pirms HTTP pieprasījuma nosūtīšanas man jāpārbauda, vai pieprasījuma pamattekstā ir iekļauti šo izslēgto rakstu ID. Ja tā, man tieši jābloķē pieprasījuma nosūtīšana.
Otrais punkts attiecas uz datubāzes vaicājumu. Tā kā spraudnis partijas indeksēšanas laikā izgūst rakstu sarakstu tieši no datubāzes, pirms datubāzes vaicājuma izpildes es noņemšu šos konkrētos ID no vaicājuma rezultātiem. No spraudņa viedokļa šie raksti vispār neeksistē, tāpēc tie netiks izgūti.
Divi ceļi, dubulta apdrošināšana. Ja vienu ceļu nevar bloķēt, ir otrs kā rezerves variants.
Pēc tam, kad to izdomāju, sāku rakstīt kodu.
Pirmajam pārtvērējam es izmantoju WordPress vietējo.pre_http_requestFiltrs. Šis āķis tiek aktivizēts, pirms WordPress veic jebkādus HTTP pieprasījumus. Mana loģika ir tāda, ka tas noteiks, vai pieprasītais URL satur...meilisearchJa pieprasījuma pamattekstā ir iekļauti izslēgto rakstu ID, pieprasījums tiks bloķēts.
Lai spraudnis neziņotu par kļūdām, man ir arī jāizveido veiksmīga atbilde. Meilisearch standarta atbildes formāts ir...{"taskUid":0,"status":"enqueued"}Es to vienkārši atgriezu, liekot spraudnim domāt, ka sinhronizācija bija veiksmīga.
Otrais pārtvērējs, ko izmantojupre_get_postsĀķis. Šis āķis tiek aktivizēts pirms WordPress izpilda datubāzes vaicājumu. Mana loģika ir tāda, ka ikreiz, kad administrators veic darbību servera aizmugurē vai kad spraudnis veic asinhronas/sinhronas darbības, izslēgtie ID ir jāapvieno...post__not_inParametros.
Pēc tam, kad biju pabeidzis to uzrakstīt, es to pārbaudīju.
Vispirms es devos uz servera aizmuguri, atvēru vienu no izslēgtajiem rakstiem, veicu dažas nelielas izmaiņas un noklikšķināju uz “Atjaunināt”. Tas tika veiksmīgi saglabāts bez kļūdām. Pēc tam es pārbaudīju Meilisearch servera aizmuguri, un raksta indekss palika nemainīgs; nekas jauns nebija parādījies.
Es vēlreiz noklikšķināju uz "Indeksēt ierakstus" un atjaunoju visu indeksu. Pēc brīža gaidīšanas es pārbaudīju Meilisearch aizmugursistēmu. Šie izslēgtie raksti joprojām bija tur.
Tas ir izdarīts.
Padziļināta analīze: Kā darbojas dubultās apdrošināšanas mehānisms?
Godīgi sakot, šis process man atgādināja kaut ko diezgan interesantu.
Ziniet, 19. gadsimta 80. gados, kad elektrība Amerikas Savienotajās Valstīs tikai sāka plaši izplatīties, daudzi rūpnīcu īpašnieki tērēja daudz naudas, lai iegādātos ģeneratorus un elektromotorus un uzstādītu tos savās rūpnīcās. Tomēr pēc uzstādīšanas daudzi cilvēki atklāja, ka ražošanas efektivitāte būtiski neuzlabojās.
为什么?
Jo viņi vienkārši nomainīja tvaika dzinēju ar elektromotoru, bet rūpnīcas kopējais izkārtojums, procesi un vadības metodes palika nemainīgas. Elektrība bija jauna, bet domāšana tās izmantošanai – veca.
Tie, kas patiesi guva labumu no elektrības uzplaukuma, patiesībā bija pirmā grupa, kas saprata, "ko elektrība patiesībā nozīmē". Viņi ne tikai mainīja savu enerģijas avotu; viņi pārveidoja visu savu ražošanas procesu.
Tas pats attiecas uz mākslīgā intelekta laikmetu. Daudzi cilvēki izmanto mākslīgo intelektu kā rīku, taču tikai retais apdomā, kādu pamatā esošo loģiku tas maina. Pats rīks ir jauns, taču domāšanas veids, kas tiek izmantots tā lietošanai, var palikt novecojis.
Piemēram, kad es iestatīju WordPress meklēšanas bloķēšanu, es, iespējams, nebūtu varējis to panākt, ja es vienkārši ievērotu spraudņa dokumentācijā norādītās standarta metodes. Tas ir tāpēc, ka Scry Search sinhronizācijas loģika vairs nav tradicionālā pieeja "saglabā vienu rakstu, sinhronizē vienu rakstu"; tai ir asinhronas rindas, partiju apstrāde un savs mehānismu kopums.
Pirms īsta izrāviena atrašanas jums ir jāizdomā, kā šis mehānisms darbojas.
Plāna ierobežojumi un piesardzības pasākumi
Tomēr man atklāti jāsaka, ka arī šis plāns nav perfekts.
Tam ir būtisks ierobežojums: tas var pārvaldīt tikai turpmākās sinhronizācijas un nevar automātiski dzēst esošos vēsturiskos ierakstus pakalpojumā Meilisearch. Citiem vārdiem sakot, ja šie raksti jau ir sinhronizēti, vecie dati joprojām ir manuāli jādzēš pakalpojumā Meilisearch informācijas panelī vai izmantojot API komandas.
Šis ir vienreizējs uzdevums; kad tas ir paveikts, jums par to vairs nav jāuztraucas. Taču man tas ir jāprecizē iepriekš, lai pēc koda izvietošanas jūs neatradīsiet šos rakstus joprojām meklēšanas rezultātos un nepieņemtu, ka kods nav stājies spēkā.
Vēl viens aspekts, kas jāatzīmē, ir tas, ka šī pieeja balstās uz WordPress pamatā esošo tīkla un datubāzes arhitektūru. Kamēr vien Scry Search spraudņa nākotnes versijas turpinās darboties, pamatojoties uz šo arhitektūru, šis pārtvērējs paliks efektīvs. Tomēr, ja tas kādreiz pārslēgsies uz pilnīgi citu sinhronizācijas mehānismu, var būt nepieciešama atkārtota pielāgošana.
Godīgi sakot, tas ir maz ticams. Visa WordPress ekosistēma ir veidota uz šīs arhitektūras, un spraudņiem praktiski nav iespējams to pilnībā apiet.
Trīs soļu ieviešanas ceļvedis
/**
* 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));
}
});
Visbeidzot, apkoposim darbības soļus.
Vispirms nokopējiet kodu uz functions.php faila pašu apakšu vai pievienojiet to, izmantojot spraudni Code Snippets. Pēc tam augšpusē...defineMasīvā ievadiet tā raksta vai lapas ID, kuru vēlaties izslēgt.
Otrais solis ir vēsturisko indeksu tīrīšana. Piesakieties savā Meilisearch informācijas panelī vai izmantojiet API komandas, lai manuāli dzēstu vecos indeksu datus izslēgtajiem rakstiem.
Trešais solis ir testēšana. Dodieties uz servera aizmuguri un veiciet nelielas izmaiņas izslēgtajā rakstā, noklikšķiniet uz “Atjaunināt” un pēc tam pārbaudiet Meilisearch servera aizmuguri. Ja jauns indekss netiek parādīts, bloķēšana ir stājusies spēkā.
Godīgi sakot, es vienmēr esmu juties nedaudz vainīgs, rakstot šāda veida tehniskus koplietošanas rakstus.
Lietas, ko es kopīgoju, dažiem cilvēkiem var būt noderīgas, bet citiem tās var būt tikai pamatdarbības.
Taču šoreiz WordPress meklēšanas bloķēšanas ieviešanas process bija patiesi ieskatu sniedzošs. Bieži vien problēmas, ar kurām mēs saskaramies, nav saistītas ar risinājumu trūkumu, bet gan ar to, ka mūsu domāšanu ierobežo esošie ietvari.
Scry Search spraudnis nodrošina filtrēšanas āķi, kas liek mums domāt, ka šī ir vienīgā iespēja. Tomēr visa WordPress arhitektūra piedāvā daudz vairāk iespēju. Pārtveršanu var panākt tīkla slānī, un to var izdarīt arī datubāzes slānī. Kamēr vien esat gatavs domāt, vienmēr ir veids, kā to izdarīt.
Tāpēc man patīk eksperimentēt ar šīm tehniskajām ierīcēm. Tā nav izrādīšanās vai mēģinājums izskatīties iespaidīgi. Vienkārši tāpēc, ka pilnīgas problēmas izpratnes sajūta sniedz neticamu gandarījumu.
Tieši tāpat kā šoreiz, sākot ar sākotnējo apjukumu, līdz pārdomām pa vidu un galīgajam risinājumam, viss process bija kā mīklas risināšana.
Noslēpums ir atrisināts, atbilde ir atklāta, izrādās, ka tas bija tik vienkārši.
Bet, ja neesi izgājis cauri šim mulsinošajam procesam, nekad nesapratīsi šo vienkāršo prieku.
Tagad, kad esat izlasījis līdz šim brīdim, ja tas jums bija noderīgi, lūdzu, atzīmējiet to ar “Patīk” un kopīgojiet to. Ja vēlaties saņemt jaunumus pirmie, varat arī sekot man.
Paldies, ka izlasījāt manu rakstu. Uz tikšanos nākamreiz.
Cerams, ka jums noderēs raksts "Kā pilnībā izslēgt konkrētu ziņas ID no sinhronizācijas ar Meilisearch programmā WordPress (Scry Search spraudnis praksē)", kas publicēts Čena Veiljana emuārā ( https://www.chenweiliang.com/ ).
Droši kopīgojiet šo raksta saiti: https://www.chenweiliang.com/cwl-34343.html
