نحوه حذف کامل شناسه یک پست خاص از وردپرس و همگام‌سازی آن با Meilisearch (افزونه جستجوی Scry در عمل)

من اخیراً روی یک وب‌سایت وردپرس کار می‌کردم و می‌خواستم یک موتور جستجوی با کارایی بالا در کل سایت اضافه کنم. بعد از جستجوی زیاد، Meilisearch را انتخاب کردم و آن را با افزونه‌ای به نام Scry Search جفت کردم.

در ابتدا همه چیز به خوبی پیش رفت. افزونه را نصب کردم، آن را پیکربندی کردم و ایندکس به صورت خودکار ایجاد شد. سرعت جستجو بسیار بالا بود و تجربه کاربری واقعاً عالی بود.

اما مشکل از اینجا شروع می‌شود.

چندین مقاله غیرمعمول در وب‌سایت وجود دارد. برخی برای آزمایش داخلی هستند، برخی صفحات فرود اختصاصی برای مشتریان خاص هستند و برخی دیگر محتوای ناتمامی هستند که نمی‌خواهیم حذف شوند. من نیاز دارم که شناسه این مقالات به طور کامل از نتایج جستجو ناپدید شود.

اینکه پیدا نمی‌شود کافی نیست؛ بلکه این است که حتی در فهرست Meilisearch هم وجود ندارد.

نحوه حذف کامل شناسه یک پست خاص از وردپرس و همگام‌سازی آن با Meilisearch (افزونه جستجوی Scry در عمل)

من فکر می‌کردم این کار ساده است؛ فقط کافی است چند شناسه را حذف کنید. مستندات افزونه باید هوک‌های مربوطه را داشته باشد؛ فقط یک فیلتر اضافه کنید و تمام.

همانطور که معلوم شد، من اشتباه می‌کردم.

چرا روش‌های مرسوم رهگیری شکست می‌خورند؟

من ابتدا قلاب فیلتر ذکر شده در مستندات رسمی را امتحان کردم. چند خط کد به functions.php اضافه کردم، آن را ذخیره کردم، backend را رفرش کردم و دوباره آن را ایندکس کردم.

سپس بک‌اند Meilisearch را بررسی کردم.

آن مقالات هنوز هم وجود دارند.

من مبهوت شده بودم.

فکر کردم کد اشتباهی نوشته‌ام، برای همین چند بار آن را بررسی کردم، اما هیچ مشکلی نداشت. سپس مشکلات گیت‌هاب افزونه را جستجو کردم و متوجه شدم که چند نفر دیگر هم با مشکلات مشابهی مواجه شده‌اند.

مشخص شد که افزونه Scry Search از یک مکانیزم صف وظایف ناهمزمان برای جلوگیری از کند شدن فرآیند ذخیره در پس‌زمینه استفاده می‌کند. این بدان معناست که وقتی در پس‌زمینه روی «ذخیره مقاله» کلیک می‌کنید، داده‌ها ممکن است فوراً به یک جدول وظایف سفارشی منتقل شوند و فیلترینگ تک مقاله‌ای معمول را دور بزنند.

نکته‌ی موذیانه‌تر این است که وقتی در پس‌زمینه روی «فهرست‌بندی پست‌ها» کلیک می‌کنید تا فهرست سراسری را بازسازی کنید، افزونه مستقیماً یک پرس‌وجوی دسته‌ای از پایگاه داده را در سطح زیرین انجام می‌دهد. در این مرحله، قلاب فیلتری که قبلاً اضافه کرده‌اید هرگز فرصتی برای اجرا پیدا نمی‌کند.

به عبارت دیگر، روش‌های مسدودسازی مرسوم فقط زمانی اعمال می‌شوند که شما به صورت دستی مقاله را ذخیره کنید. اما منطق همگام‌سازی Scry Search بسیار پیچیده‌تر از آن چیزی است که تصور می‌کنید.

کد اصلی رهگیر بیمه مضاعف

بعد از اینکه کمی فکر کردم، فهمیدم که این موضوع را نمی‌توان همین‌طور رها کرد.

از آنجایی که قلاب مرسوم فقط نقطه ورود "ذخیره تک مقاله" را کنترل می‌کند، باید راهی پیدا کنم تا آن را از جاهای دیگر نیز مسدود کنم.

من دو راه پیش رو گذاشته‌ام.

اولین مشکل، انتهای انتقال شبکه است. چه همگام‌سازی تک‌مقاله‌ای باشد و چه همگام‌سازی دسته‌ای، داده‌های نهایی هنوز باید از طریق درخواست‌های HTTP به سرور Meilisearch ارسال شوند، درست است؟ بنابراین، قبل از ارسال درخواست HTTP، باید بررسی کنم که آیا بدنه درخواست شامل شناسه‌های آن مقالات حذف‌شده است یا خیر. در این صورت، باید مستقیماً ارسال درخواست را مسدود کنم.

نکته دوم مربوط به کوئری پایگاه داده است. از آنجایی که افزونه در طول فهرست‌بندی دسته‌ای، فهرست مقالات را مستقیماً از پایگاه داده بازیابی می‌کند، من آن شناسه‌های خاص را قبل از اجرای کوئری پایگاه داده از نتایج کوئری حذف می‌کنم. از دیدگاه افزونه، این مقالات اصلاً وجود ندارند، بنابراین بازیابی نخواهند شد.

دو مسیر، بیمه مضاعف. اگر یک مسیر قابل مسدود شدن نباشد، مسیر دیگری به عنوان پشتیبان وجود دارد.

بعد از اینکه فهمیدم، شروع به نوشتن کد کردم.

برای اولین interceptor، از نسخه بومی وردپرس استفاده کردم.pre_http_requestفیلتر. این هوک قبل از اینکه وردپرس هرگونه درخواست HTTP ارسال کند، فعال می‌شود. منطق من این است که تشخیص می‌دهد آیا URL درخواستی شامل ... است یا خیر.meilisearchاگر بدنه درخواست شامل شناسه‌های مقالات حذف‌شده باشد، درخواست مسدود خواهد شد.

برای جلوگیری از گزارش خطا توسط افزونه، باید یک پاسخ موفق را جعل کنم. قالب استاندارد پاسخ برای Meilisearch ... است.{"taskUid":0,"status":"enqueued"}من به سادگی این را برگرداندم، و باعث شدم افزونه فکر کند که همگام‌سازی موفقیت‌آمیز بوده است.

دومین رهگیر که استفاده کردمpre_get_postsقلاب. این قلاب قبل از اینکه وردپرس یک کوئری پایگاه داده را اجرا کند، فعال می‌شود. منطق من این است که هر زمان که یک مدیر عملیاتی را در بک‌اند انجام می‌دهد، یا وقتی یک افزونه عملیات ناهمزمان/همزمان را انجام می‌دهد، شناسه‌های حذف‌شده باید در... ادغام شوند.post__not_inدر پارامترها.

بعد از اینکه نوشتنش تمام شد، آن را آزمایش کردم.

اول، به پنل مدیریت رفتم، یکی از مقالات حذف شده را باز کردم، چند تغییر جزئی ایجاد کردم و روی به‌روزرسانی کلیک کردم. بدون هیچ خطایی با موفقیت ذخیره شد. سپس پنل مدیریت Meilisearch را بررسی کردم و فهرست مقاله بدون تغییر باقی ماند؛ هیچ چیز جدیدی ظاهر نشده بود.

دوباره روی «فهرست پست‌ها» کلیک کردم و کل فهرست را دوباره ساختم. بعد از مدتی انتظار، بک‌اند Meilisearch را بررسی کردم. آن مقالات حذف‌شده هنوز آنجا بودند.

تمام شد.

تحلیل عمیق: سازوکار بیمه مضاعف چگونه کار می‌کند؟

راستش را بخواهید، این روند من را یاد یک چیز کاملاً جالب انداخت.

می‌دانید، در دهه ۱۸۸۰، زمانی که برق تازه در ایالات متحده فراگیر شده بود، بسیاری از صاحبان کارخانه‌ها پول زیادی را صرف خرید ژنراتور و موتور برق و نصب آنها در کارخانه‌های خود کردند. با این حال، پس از نصب، بسیاری از مردم متوجه شدند که راندمان تولید به طور قابل توجهی بهبود نیافته است.

为什么؟

زیرا آنها به سادگی موتور بخار را با یک موتور الکتریکی جایگزین کردند، اما طرح کلی، فرآیندها و روش‌های مدیریت کارخانه بدون تغییر باقی ماند. برق جدید بود، اما طرز فکر استفاده از آن قدیمی بود.

کسانی که واقعاً از رونق برق بهره‌مند شدند، در واقع اولین گروهی بودند که فهمیدند «برق واقعاً به چه معناست.» آنها فقط منبع تغذیه خود را تغییر ندادند؛ بلکه کل فرآیند تولید خود را از نو طراحی کردند.

همین امر در مورد عصر هوش مصنوعی نیز صدق می‌کند . بسیاری از مردم از هوش مصنوعی به عنوان یک ابزار استفاده می‌کنند، اما تعداد کمی از آنها منطق اساسی تغییر آن را در نظر می‌گیرند. خود ابزار جدید است، اما طرز فکر مورد استفاده برای استفاده از آن ممکن است قدیمی باقی مانده باشد.

برای مثال، وقتی داشتم مسدودسازی جستجوی وردپرس را تنظیم می‌کردم، اگر فقط از روش‌های استاندارد موجود در مستندات افزونه پیروی می‌کردم، احتمالاً نمی‌توانستم آن را به کار بیندازم. دلیلش این است که منطق همگام‌سازی Scry Search دیگر رویکرد سنتی «ذخیره یک مقاله، همگام‌سازی یک مقاله» نیست؛ بلکه صف‌های ناهمزمان، پردازش دسته‌ای و مجموعه مکانیسم‌های خاص خود را دارد.

قبل از اینکه بتوانید به یک موفقیت واقعی دست پیدا کنید، باید بفهمید که این مکانیسم چگونه کار می‌کند.

محدودیت‌ها و ملاحظات طرح

با این حال، باید رک و پوست کنده بگویم که این طرح هم بی‌نقص نیست.

این یک محدودیت قابل توجه دارد: فقط می‌تواند همگام‌سازی‌های آینده را مدیریت کند و نمی‌تواند به‌طور خودکار رکوردهای تاریخی موجود در Meilisearch را پاک کند. به عبارت دیگر، اگر قبلاً آن مقالات را همگام‌سازی کرده‌اید، هنوز باید داده‌های قدیمی را به‌صورت دستی در داشبورد Meilisearch یا با استفاده از دستورات API حذف کنید.

این یک کار یک‌باره است؛ وقتی انجام شد، دیگر لازم نیست نگران آن باشید. اما باید این را از قبل روشن کنم، تا پس از استقرار کد، آن مقالات را هنوز در نتایج جستجو پیدا نکنید و فرض نکنید که کد اعمال نشده است.

نکته‌ی دیگری که باید به آن توجه کرد این است که این رویکرد به معماری شبکه و پایگاه داده‌ی زیربنایی وردپرس متکی است. تا زمانی که نسخه‌های بعدی افزونه‌ی Scry Search بر اساس این معماری به کار خود ادامه دهند، این رهگیر همچنان مؤثر خواهد بود. با این حال، اگر زمانی به یک مکانیسم همگام‌سازی کاملاً متفاوت تغییر کند، ممکن است سازگاری مجدد ضروری باشد.

راستش را بخواهید، این بعید است. کل اکوسیستم وردپرس بر اساس این معماری ساخته شده است و عملاً غیرممکن است که افزونه‌ها بتوانند آن را به طور کامل دور بزنند.

راهنمای سه مرحله‌ای برای اجرا

/**
 * 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));
    }
});

در نهایت، بیایید مراحل عملیات را خلاصه کنیم.

ابتدا، کد را در انتهای فایل functions.php خود کپی کنید، یا آن را با استفاده از افزونه Code Snippets اضافه کنید. سپس، در بالای...defineدر آرایه، شناسه مقاله یا صفحه‌ای را که می‌خواهید حذف کنید، وارد کنید.

مرحله دوم، پاکسازی فهرست‌های قدیمی است. وارد داشبورد Meilisearch خود شوید، یا از دستورات API برای حذف دستی داده‌های فهرست قدیمی برای مقالات حذف شده استفاده کنید.

مرحله سوم آزمایش است. به بخش مدیریت بروید و هرگونه تغییر جزئی در مقاله حذف شده ایجاد کنید، روی به‌روزرسانی کلیک کنید و سپس بخش مدیریت Meilisearch را بررسی کنید. اگر هیچ فهرست جدیدی ظاهر نشد، مسدودسازی اعمال شده است.

راستش را بخواهید، من همیشه از نوشتن این نوع مقالات فنی که در مورد اشتراک‌گذاری نوشته‌ام، کمی احساس گناه کرده‌ام.

چیزهایی که به اشتراک می‌گذارم ممکن است برای بعضی افراد مفید باشد، اما برای بعضی دیگر ممکن است فقط عملیات اساسی باشند.

اما روند پیاده‌سازی مسدودسازی جستجوی وردپرس این بار واقعاً هوشمندانه بود. اغلب، مشکلاتی که با آنها مواجه می‌شویم به دلیل فقدان راه‌حل نیستند، بلکه به این دلیل هستند که تفکر ما توسط چارچوب‌های موجود محدود شده است.

افزونه Scry Search یک قلاب فیلترینگ ارائه می‌دهد و ما را به این باور می‌رساند که این تنها گزینه است. با این حال، کل معماری وردپرس امکانات بسیار بیشتری را ارائه می‌دهد. رهگیری را می‌توان در لایه شبکه و همچنین در لایه پایگاه داده انجام داد. تا زمانی که مایل به فکر کردن باشید، همیشه راهی وجود دارد.

به همین دلیل است که از سر و کله زدن با این ابزارهای فنی لذت می‌برم. این کار برای خودنمایی یا تلاش برای چشمگیر به نظر رسیدن نیست. صرفاً به این دلیل است که احساس درک کامل یک مشکل فوق‌العاده رضایت‌بخش است.

درست مثل این دفعه، از سردرگمی اولیه، تا تأمل در میانه، و تا راه‌حل نهایی، کل فرآیند مثل حل یک معما بود.

معما حل شده، جواب آشکار شده، معلوم شده که خیلی ساده بوده.

اما اگر آن فرآیند گیج کننده را طی نکرده باشید، هرگز این لذت ساده را درک نخواهید کرد.

حالا که تا اینجا را خوانده‌اید، اگر برایتان مفید بود، لطفاً آن را لایک کنید و به اشتراک بگذارید. اگر می‌خواهید زودتر از بقیه از جدیدترین‌ها مطلع شوید، می‌توانید من را دنبال کنید.

ممنون که مقاله من را خواندید. دفعه بعد می‌بینمتان.

امیدوارم مقاله "چگونه شناسه پست خاصی را به طور کامل از همگام‌سازی با Meilisearch در وردپرس (افزونه جستجوی Scry در عمل) حذف کنیم" که در وبلاگ چن ویلیانگ ( https://www.chenweiliang.com/ ) به اشتراک گذاشته شده است، برای شما مفید باشد.

لینک این مقاله را به اشتراک بگذارید: https://www.chenweiliang.com/cwl-34343.html

برای کشف ترفندهای مخفی بیشتر🔑، به کانال تلگرام ما بپیوندید!

اگر دوست داشتید به اشتراک بگذارید و لایک کنید! اشتراک گذاری ها و لایک های شما انگیزه ادامه دار ماست!

 

发表 评论

您的邮箱地址不会被公开。必填项已用*标注

رفته به بالا