Back to "إصلاح الموقع"

This is a viewer only at the moment see the article on how this works.

To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk

This is a preview from the server running through my markdig pipeline

ASP.NET PostgreSQL RRF Search

إصلاح الموقع

Wednesday, 14 January 2026

البحث هو أحد تلك الصفات التي يضعها الجميع تحت تقديره. بشكل مفهومي صحيح ولكن خطأ بصفة نصية. عندما يفشل البحث في تلك الحالات, لا يعتقد المستخدمينM SK2 لا يفكرون MSC3 حالة حافةMST4 MST5 يعتقدون أن الموقع قد أُكسر

إنه "مسك0" أيضاً من المفترض أن "مسک1" يرتكز هذا الموقع منذ بداية "مكس2" و "مكسي3" نظرت إلى البحث المفتوح, عملت على البحث النصي الكامل بـPostgreSQL معها 'شيء الحافز فيكتوري لكنه لم يكن أبدا سعيداً به مختلطة أنا especially now I'm building a search tool in وضوحRAG حسناً ظننت أنه يجب أن أصلحها أخيراً سواء كان ذلك هو أو لا هو أمر آخر.

هذا المقال لا يتعلق بـ"مسك0" بل ببناء محرك بحث من الصفر. "مسك1" بل "مسک2" يتعلق بحل الحواف الحادة لنظام PostgreSQL الكامل. "ماسك3" البحث النصي في نظام الإنتاج الحقيقي. "موسك4" سأقوم ببحث عن الاختلافات المحددة التي واجهتها. "ميسك6" لماذا حدثت. "مهسك7" وإجراء الإصلاحات العملية اللازمة لجعل البحث يتصرف كما يتوقعه المستخدمون.

بناء على أعمال سابقة: هذا المقال يمد تطبيق البحث الدلالي التي أضافت البحث الهجين مع دمج الرتبة المتقابلة (RRF). تلك المقالة السابقة تغطي أساسا -جمع PostgreSQL كاملةM SK3بحث النص مع بحث الفيكتور QdrantMSC4 هذه المقالة تصلح الحالات الهوائية التي تفتقدها التنفيذ : الأختصارات التي لا تطابق مع | ' لا تتطابق مع ـ , المصطلحات التقنية مع الحروف الخاصة |, و الاسئلة الطبيعية التي يكسرها تحليل Postgre SQL |

إن البنية التحتية للبحث الدلالي تخدم أهدافاً مزدوجة و يوفر طبقة استرجاع ل محامي GPT نظام RAG -أعمال كتابة يقوم برسم पदों الجديدة باستخدام الموقع' المحتوى المتوفر كقاعدة للمعرفة بناء جزء "حامل GPT" – على الدمجات و البحث فيكتوري.

المشاكل

1. نتائج فارغة أظهرت مقالات عشوائية

عندما أعاد البحث لا نتائج , كان النظام يعرض مقالات قديمة عشوائية بدلاً من إقتراحات مفيدة . هذا إنتهى من مبدأ الحد الأدنى من الإثارة للدهشة | - | توقع المستخدمين إما نتائج ذات مغزى أو واضحة |" | لم يعثر على تطابق |" | رسالة مع الملاحظات الأخيرة كإقتراح | . | هذا جعل الأمر يبدو وكأن البحث قد نجح |

الحل: تم تعديله BlogSearchService.HybridSearchWithPagingAsync() لإكتشاف عندما يعيد البحث نتائج صفر وتعود لإظهار الملاحظات الأخيرة مرتبة بال fecha descending. أضافت NoMatchFound علم إلى BasePagingModel بحيث يمكن للواجهة أن تظهر رسالة مناسبة مثل "لم يُعثر على تطابق . هل كنتم تقصدون واحدة من هذه

// No match found - return recent posts as suggestions
if (noMatchFound)
{
    Log.Logger.Information("No search results for '{Query}', returning recent posts as suggestions", query);
    return await GetRecentPostsAsSuggestions(targetLanguage, startDate, endDate, page, pageSize);
}

2. اختصارات مثل "DiSEM SK2 Weren't متطابقة

نظام البحث النصي الإنجليزي تلقائي بـ PostgreSQL ' يحوّل إحصائياً على الحروف المختصرة , لكن العولمة والإستنتاج تجعل الحالة القصيرة | , | حالة |- | المصطلحات الهامة غير موثوق بها في الواقع | МSK4 | عندما تبحث عن | | مSK5 | DiSE | ومSK6 | فإنه ينزل إلى | ما | 7 | dise | و بعد ذلك قاموس اللغة الإنجليزية قد يتخلص منه أو يخصص له وزناً منخفضاً | , | مما يؤدي إلى أن البحث النصية الكاملة ــ - | تضيع المقالات التي تحتوي بوضوح | ام | 11 | DISE ٬ م | 12 | في عنوانها و المحتوى | أم | 13

الحل: أضفنا إكتشاف الأحرف الرمزية (مواضيع ≤6 حروف مع حرفات كبيرة) وقضيةM SK4التراجع الغير حساس للأرقام الفرعية باستخدام PostgreSQLMSC5s ILIKE. هذا يكمل البحث النصي الكامل- بدلاً من استبداله (انظروا إلى ملاحظات الأداء في الأسفل لسبب قبول هذا

// Detect if query looks like an acronym or short term
var isAcronymLike = query.Length <= 6 && query.Any(char.IsUpper);

// Add substring search for acronyms
searchQuery = searchQuery.Where(x =>
    EF.Functions.ILike(x.Title, $"%{acronym}%")
    || EF.Functions.ILike(x.PlainTextContent, $"%{acronym}%"));

البحث عن "ASP.NETM SK2 أو "CMSC4 سيفشل لأن محرر البحث النصي PostgreSQLMska5 يتعامل مع المراحل ورمزات الهش كمحدودينMske6 ويقسم "AspMsko8NET" إلى "A SPMsku11 و "net" كعلامة مستقلةMsek14 وهذا يعني أن البحث عن المفهوم الدقيق لن يعمل'Msco16

الحل: خلقت SearchQueryParser التي تعترف بالمصطلحات التقنية المشتركة وتستبدلها بإصدارات قابلة للبحث

private static readonly Dictionary<string, string> TechnicalTerms = new(StringComparer.OrdinalIgnoreCase)
{
    ["asp.net"] = "aspnet",
    ["c#"] = "csharp",
    [".net"] = "dotnet",
    ["f#"] = "fsharp",
    ["node.js"] = "nodejs",
    // ... more terms
};

4. أسئلة مثل "ASPM SK2NET and Alpine" لم تعمل

PostgreSQL يتعامل مع "و" ككلمة توقف وتزيلها من ال検索اتM SK2 تدمج مع مسألة الخصائص الخاصة , سؤال طبيعي مثل |" |ASP | . |NET | and Alpine |

الحل: تم تنفيذ محرك بحث غوغل - يتعامل مع كلمات التوقف بذكاء ويدعم مشغلات البحث المتقدمة

الحلول

Google-مشغلات البحث فيStyle

لقد قمت بتطبيق SearchQueryParser الصنف الذي يحل الاسئلة مع الدعم ل:

  1. العبارات المقتطفة: "exact match" - يبحث عن الجملة بالضبط
  2. شروط غير محصّلة: -unwanted - يبعد عن النتائج التي تحتوي على هذا المصطلح
  3. البطاقات البرية: ASP* - تطابق "ASP", "AspNETM SK4 ♫"ASPNetCoreMSC6 إلخ |.
  4. الشروط التقنية: يتعامل تلقائيا "ASP.NETM SK3 "CMSC5 | | ".NET |" | إلخ |

يستخدم التحليلي نمط regex المكتمل لترميز الشؤال:

[GeneratedRegex(@"""([^""]+)""|(-)?(\S+)", RegexOptions.Compiled)]
private static partial Regex QueryTokenRegex();

public ParsedQuery Parse(string query)
{
    var matches = QueryTokenRegex().Matches(processedQuery);

    foreach (Match match in matches)
    {
        // Quoted phrase
        if (match.Groups[1].Success)
        {
            var phrase = match.Groups[1].Value.Trim();
            result.Phrases.Add(phrase);
            continue;
        }

        // Excluded term (starts with -)
        if (match.Groups[2].Success)
        {
            var term = match.Groups[3].Value.Trim();
            result.ExcludeTerms.Add(term.ToLowerInvariant());
            continue;
        }

        // Regular term or wildcard
        var token = match.Groups[3].Value.Trim();
        if (token.Contains('*'))
        {
            result.WildcardTerms.Add(token.Replace("*", ""));
        }
        else if (!StopWords.Contains(token))
        {
            result.IncludeTerms.Add(token.ToLowerInvariant());
        }
    }
}

بناء "PostgreSQL tsquery"

يصدر الخوارزميات البيانات الهيكلية التي تم تحويلها إلى PostgreSQL to_tsquery لأننا ' ننتج تركيبة مبنية - لا websearch_to_tsquery لأننا' لقد قمنا بتحليل المشغلين بأنفسنا- -, مما يعطينا المزيد من التحكم في كيفية دمج الشروط .

public string BuildTsQuery(ParsedQuery parsed)
{
    var queryParts = new List<string>();

    // Add include terms with AND
    foreach (var term in parsed.IncludeTerms)
    {
        queryParts.Add(term);
    }

    // Add wildcard terms with :* suffix
    foreach (var term in parsed.WildcardTerms)
    {
        queryParts.Add($"{term}:*");
    }

    return queryParts.Count > 0 ? string.Join(" & ", queryParts) : string.Empty;
}

لماذا لا نستخدم فقط websearch_to_tsquery? لأنه لا يزال يفشل في المصطلحات التقنية, الإختلافات, والドメインM SK2 صيغة خاصة MSC3 ولا يقدم أي مقابض للتصنيف الهجين أو التراجعات . عن طريق تحليل أنفسناMST5 يمكننا التعامل مع هذه الحالات المتطرفة قبل أن تصل إلى PostgreSQL

بحث بناء مُحسن

الـ BuildSearchQuery تم إعادة كتابة الطريقة بالكامل لإستخدام بنية الشؤال المنحلة. baseQuery بالفعل تصفيه باللغة, نطاق التاريخ, وقابلية الرؤية - نحنM SK3 نضيف البحثMSC4 الشروط المحددة في الأعلىMNK5

private IOrderedQueryable<BlogPostEntity> BuildSearchQuery(
    string query,
    string language,
    DateTime? startDate,
    DateTime? endDate,
    string order)
{
    var parsed = _queryParser.Parse(query);
    IQueryable<BlogPostEntity> searchQuery = baseQuery;

    // Handle phrases (exact substring matching)
    foreach (var phrase in parsed.Phrases)
    {
        searchQuery = searchQuery.Where(x =>
            EF.Functions.ILike(x.Title, $"%{phrase}%")
            || EF.Functions.ILike(x.PlainTextContent, $"%{phrase}%")
            || x.Categories.Any(c => EF.Functions.ILike(c.Name, $"%{phrase}%")));
    }

    // Build tsquery for include terms and wildcards
    var tsQuery = _queryParser.BuildTsQuery(parsed);

    // Apply full-text search if we have terms
    if (!string.IsNullOrWhiteSpace(tsQuery))
    {
        searchQuery = searchQuery.Where(x =>
            x.SearchVector.Matches(EF.Functions.ToTsQuery("english", tsQuery))
            || x.Categories.Any(c =>
                EF.Functions.ToTsVector("english", c.Name)
                    .Matches(EF.Functions.ToTsQuery("english", tsQuery))));
    }

    // Handle acronyms with case-insensitive substring search
    // This supplements full-text search (additive OR), not replaces it
    var acronymTerms = parsed.IncludeTerms
        .Concat(parsed.WildcardTerms)
        .Where(t => _queryParser.IsAcronymLike(t))
        .ToList();

    foreach (var acronym in acronymTerms)
    {
        searchQuery = searchQuery.Where(x =>
            EF.Functions.ILike(x.Title, $"%{acronym}%")
            || EF.Functions.ILike(x.PlainTextContent, $"%{acronym}%"));
    }

    // Handle excluded terms (must NOT contain these)
    foreach (var excludeTerm in parsed.ExcludeTerms)
    {
        searchQuery = searchQuery.Where(x =>
            !EF.Functions.ILike(x.Title, $"%{excludeTerm}%")
            && !EF.Functions.ILike(x.PlainTextContent, $"%{excludeTerm}%")
            && !x.Categories.Any(c => EF.Functions.ILike(c.Name, $"%{excludeTerm}%")));
    }

    return orderedQuery;
}

أمثلة البحث

هنا بعض الأمثلة على أداء البحث المحسن:

البحث الأساسي

DiSE

✅ الآن يتطابق المقالات مع "DiSE" في عنوان أو المحتوى (caseM SK4insensitiveMSC5

الشروط التقنية

ASP.NET

✅ يجد مقالات عن ASP.NET ( محولة تلقائياً إلى "aspnetM SK4 للبحث الكاملMSC5text searchMスク6

البحث في الجملة

"semantic search"

✅ يجد جملة دقيقة "بحث لغوي" في المقالات

شروط غير محصّلة

ASP.NET -Core

✅ يجد مقالات ASP.NET لكن يبعد عنهم تلك التي تشير إلى "CoreM SK3

البطاقات البرية

ASP*

✅ تتطابق "ASP", "AspNETM SK4 |" |ASPNetCore | ", | إلخ

السؤال المعقد

"full text search" PostgreSQL -MySQL

✅ يجد المقالات التي تحتوي على جملة دقيقة "بحث عن النص الكامل" وذكرات PostgreSQLM SK3 لكن بإستثناء المقالات التى تشير إلى MySQL

مثال قبل وبعد

السؤال: ASP.NET and Alpine

قبل (broken):

  • "ASPM SK1NET" تقسم إلى "AspMSC4 + | | "NET |"
  • "and" أزيلت ككلمة توقف
  • Result: searches only for M SK1Alpine"

بعد (fixed):

  • "ASPM SK1NET" حول إلى "aspnetMSC4
  • "and" محفوظة بطريقة ذكية كجزء من إهتمام استبيان المستخدم
  • "Alpine" بحث بشكل طبيعي
  • Result: يجد مقالات حول كلا ASP.NET و Alpine

تكامل التصنيف لـ RRF

يتم دمج البحث مع السلسلة المتباعدة (RRF) كما تم تنفيذه في مقال البحث الدلالي السابق. RRF هنا يستخدم ل التصنيف, لا يعيد الذاكرة - إنه يجمع بالفعل- نتائج تم استرجاعها من BM

// Fuse using RRF with category/freshness boosts
var fusedDtos = _ranker.FuseResults(bm25Results, vectorResults, query);

الخوارزمية RRF تستخدم 1/(k+rank) حيث يجمع k=60 النتائج من مصادر متعددة , ثم يطبق مضاعفات :

  • تناسب التصنيف: +2.0
  • تطابق शीर्षक: +1.0
  • الشباب: التدهور النسبي على مدى 1 سنة

لتطبيق RRF الكامل وكيفية عمل البحث الهجين, أنظر البحث الدلالي في العمل. للغوص العميق في المداخلات والتشابه الفيكتوري , см. بناء جزء "حامل GPT" -. نفس البنية التحتية تمكن كلا من المستخدم- التوجه للبحث والبحث عن RAG من أجل الذكاء الاصطناعي

العمارة التقنية

إنبوب الإعتماد

المكونات الجديدة تم تسجيلها كخدمات:

services.AddSingleton<SearchQueryParser>();
services.AddSingleton<SearchRanker>();
services.AddScoped<BlogSearchService>();

SearchQueryParser و SearchRanker هي مجردtons لأنّها ' لا تملك حالة وثابتة , تار - آمن , ويمكن إستخدامها مرة أخرى في جميع الطلبات BlogSearchService تم تحديد نطاقها لأنها تتمكن من الوصول إلى سياق البيانات.

تدفق التساؤل

  1. يدخل المستخدم بحثاً → محرك البحث
  2. تحليل الاسئلة → SearchQueryParser يقسم إلى مكونات مبنية
  3. البحث الدلالي (if enabled) → قاعدة بيانات векторية Qdrant مع مداخلات ONNX
  4. PostgreSQL كاملة-بحث نصي (متوفر دائماM SK2 → BM25-تطابق كلمات المرور على أساس
  5. الإنصهار RRF → يجمع كلا مجموعتين النتائج مع التصنيف / تحسن الطابع
  6. لا النتائج → يعيد ال posts الأخيرة كإقتراحات

نفس عنصر البحث الدلالي يستخدم أيضاً من قبل محامي GPT نظام لإستقاط المدونات السابقة ذات الصلة للAI-كتابة المساعدة. شاهد الجزء 4 detailed on the ingestion pipeline.

تخطيط قاعدة البيانات

البحث يعتمد على تحليل مسبق SearchVector ستجد ستونا في BlogPosts جدول:

ALTER TABLE mostlylucid."BlogPosts"
ADD COLUMN "SearchVector" tsvector
GENERATED ALWAYS AS (
    to_tsvector('english',
        coalesce("Title", '') || ' ' ||
        coalesce("PlainTextContent", '')
    )
) STORED;

CREATE INDEX idx_blog_posts_search_vector
ON mostlylucid."BlogPosts"
USING GIN ("SearchVector");

GIN (index generalized Inverted ) يوفر بحثاً سريعاً كاملاً | - | text search across large text corpora |.

وجهات النظر في الأداء

لماذا اللافتة لكلمة اختصارية?

بينما ILIKE (caseM SK1insensitive LIKE) is slower than full -text searchMST4 itMSC5s necessary for acronyms becauseMS:

  1. الجمل الكاملة -البحث النصي يُطَمِّرَي /يمكّن من الوصول إلى المصطلحات | , | كسر الأوتار الفائقة القصيرة
  2. الأختصارات هي عادة قصيرة (≤6 حروف ), محدودة تأثير الأداء
  3. يتم إضافة الحالة فقط عند الحاجة (حرف اختصارية مكتشفة)

هذه المقاربة لن تتدرج إلى بحث فرعي عشوائي عبر ملايين الأ行ات -لكن بالنسبة للحرف الرمزية المستهدفة فإنها 'suitable

تصنيف كثافة الغلاف PostgreSQL (ts_rank_cd)

offers two ranking functions for full-text search

  • ts_rank: التردد الأساسي للأفكار ( كم مرة تظهر الأفكار
  • ts_rank_cd: تصنيف كثافة الغطاء (كيف تبدو المصطلحات قريبة مع بعضها البعض

نحن نستخدم ts_rank_cd لأنها توفر علاقة بـ BM25- بأخذ في الإعتبار اقتراب المدى:

// Order by cover density ranking - rewards term proximity
orderedQuery = searchQuery.OrderByDescending(x =>
    x.SearchVector.RankCoverDensity(EF.Functions.ToTsQuery("english", tsQuery)));

لماذا ts_rank_cd هو أفضل

Metric ts_rank ts_rank_cd
الخوارزمية تردد المدى كثافة الغطاء (مقاربة ) S
العديد من -សំណួរ الكلمات يحسب المصطلحات منفصلاً مصطلحات الجائزة تظهر معاً ≥
مثال: "طاولة الدوكرM SK2 مقالة مع "دوكير" 50 تعطي علامة مرتفعة مقالة بـ " علبة الدوكير " معا تعطي علامات أعلى
الأداء سريع بطيئ نسبياً , لا يزال يرفع من إحصاء الـGIN
السلوك العد البسيط تقريبية BM

هذا هو تحسين الفوز السريع - أعلى نسبية في التصنيف مع تطبيق صفر-حساب مستوىM SK2 كل التصنيف يحدث في PostgreSQL باستخدام إحصاء GIN موجود على SearchVector.

الإشارات:

تحسينات الأداء الإضافية

أكثر من إصلاح أداء البحث, تحسينات رئيسية عديدة لتحسين الأداء:

1. تخزين اللغة

اللغات المتاحة نادراً ما تتغير ولكن تم سؤالها في كل طلب بحث

private static readonly TimeSpan LanguageCacheDuration = TimeSpan.FromHours(1);
private static List<string>? _cachedLanguages;
private static DateTime _languageCacheExpiry = DateTime.MinValue;
private static readonly SemaphoreSlim _cacheLock = new(1, 1);

التأثير: يزيل 1 سؤال قاعدة بيانات لكل طلب بحث

2. أسئلة ILIKE المزدحمة

الرمز الأصلي المستعمل foreach حلقات تخلق العديد من فقرات أين. الآن مدمجة في تعبيرات واحدة:

// BEFORE: Multiple WHERE clauses
foreach (var acronym in acronymTerms)
{
    searchQuery = searchQuery.Where(x =>
        EF.Functions.ILike(x.Title, $"%{acronym}%"));
}

// AFTER: Single batched WHERE
if (acronymTerms.Count > 0)
{
    searchQuery = searchQuery.Where(x =>
        acronymTerms.Any(acronym =>
            EF.Functions.ILike(x.Title, $"%{acronym}%")));
}

التأثير: SQL أكثر سلاسة, ~5-10% أسرع لكثير من الأسئلة

3. Index Covering for Common Queries

أضفنا مؤشراً جزئياً مع ستloupes INCLUDE لنمط الوصول المكرر:

CREATE INDEX idx_blog_posts_search_covering
ON mostlylucid."BlogPosts" ("LanguageId", "IsHidden", "ScheduledPublishDate")
INCLUDE ("Id", "Slug", "Title", "PublishedDate")
WHERE "IsHidden" = false;

التأثير: يُمكن index-مسح فقط - PostgreSQL لا يحتاج إلى ' الوصول إلى كومة الجدول

4. أزيل ما هو غير ضروري بما في ذلك

EF Core's Include() loads full navigation entities. Removed where only navigation properties used in WHERE clauses:

// BEFORE: Loads full LanguageEntity into memory
.Include(x => x.LanguageEntity)
.Where(x => x.LanguageEntity.Name == "en")

// AFTER: EF translates navigation property without loading entity
.Where(x => x.LanguageEntity.Name == "en")

التأثير: ~5-10% تخفيض الذاكرةM SK2 نقل أقل من البيانات من قاعدة البيانات.

الإشارات:

استراتيجية تحسين الأسئلة

يبنى البحث أين ستستخدم الجمل بشكل متزايد تركيب شجرة التعبير EF Core's:

IQueryable<BlogPostEntity> searchQuery = baseQuery;

// Each filter added conditionally - PostgreSQL optimizes the final query
if (parsed.Phrases.Count > 0) { searchQuery = searchQuery.Where(...); }
if (!string.IsNullOrWhiteSpace(tsQuery)) { searchQuery = searchQuery.Where(...); }
if (acronymTerms.Count > 0) { searchQuery = searchQuery.Where(...); }

هذا ينتج سؤال واحد مُحسن من SQL بدلاً من عدة رحلات دائرية. PostgreSQL' يستطيع مخطط الطلب استخدام الإحصائيات والمؤشرات بشكل فعال عندما يرى فقرة أين كاملة

ملخص الأداء

التأثير المتراكم لكل التحسينات:

تحسين تأثير البطاقة تأثير تحميل البيانات
ال caching للغة الحد الأدنى
أزيلوا من ضمنهم() ≥-5-10% نقل البيانات أقل
بطاقة ILIKE -5-10% Cleaner SQL
المؤشر المغطى -20-30% المؤشر - فقط المسح
tsM SK1rank_cd مماثلة علاقة أفضل
إصلاح السجل (مساريات الطريق) NM SK4A يمنع البيانات الميتة M

التحسن المتوقع الكلي: 30-50% بحث أسرع مع انخفاض كبير في ضغط قاعدة البيانات.

الدروس المستفادة

  1. لا أفترض أن البحث النصي يعالج كل شيء: حاسوبي القضبان مثل الأختصارات والحرف الخاصة يحتاجون إلى معالجة خاصة

  2. دمج المقاربات المتعددة: البحث الكلي- البحث النصي (BMM SK3 | | + البحث الدلالي |( |vectors | МSK6 | + | فرعية الخداعات توفر تغطية أفضل من أي طريقة واحدة

  3. تم تشكيل توقعات المستخدم من قبل غوغل: دعم العبارات المشروحة, استثناءاتM SK2 وطاقات عشوائية يجعل البحث يبدو طبيعيا لأن المستخدمين يعرفون هذه المشغلات

  4. توفر تراجعات مفيدة: عندما يفشل البحث, لا ' لا يظهر أي شيء - يظهر الملاحظات الأخيرة وجعل الأمر واضحا أنه لم يعثر على تطابق

  5. Parse, don't hack: محرر الطلب المناسب هو أكثر نظافة وأكثر قابلية للحفاظ من سلسلة من عمليات التلاعب بالسلسلة.

  6. إستفادة من PostgreSQL's بنيت-في التصنيف: استخدام ts_rank_cd بدلاً من ts_rank بالنسبة لل BM25-ماثل الجدوىM SK1 تصنيف كثافة الغطاء يأخذ في الإعتبار قريبة المصطلح - الفوز السريع الذي يحسن جودة النتائج مع تطبيق صفر -رمز مستوىMSC4

  7. Profil before optimizing: bottlenecks "obviousM SK2 bottlenes (FTS parsing) werenMSC5t the real problemMska6 language lookupsMsko7 excessive includesMske8 and missing indexes had bigger impact than expectedMsek9

  8. عمليات قاعدة بيانات بطاقات: متعددة foreach حلقات تخلق فقرات منفصلة عن بعضها تنتج SQL . استخدام Any() أو All() لتجمع في تعبيرات واحدة.

تحسينات مستقبلية

تحسينات محتملة للمستقبل, تصنف بالقلق:

تحسينات البحث:

  • تطابق مبهم: مسافة ليفينشتين لتحمل النمط
  • اختصار التمدد: "رسالة مدونية" ♫→ | | " | مقالة

تحسينات التحليل:

  • تصفية التصنيف: category:ASP.NET المشغل
  • نطاق التاريخ: after:2025-01-01 المشغل

تحسينات التصنيف:

  • توضيح النتائج: أظهر الأجزاء المتطابقة من النص في النتائج
  • اضغط على - عبر التعقب: تعلم من سلوك المستخدم لتحسين التصنيف

قابلة للملاحظة:

  • تحليل البحث: تتبع الأسئلة الشائعة والبحث الفاشلة لتحديد الفجوات

الاستنتاجات

صناعة البناء -بحث الدرجة يتطلب إصلاح الحواف و تحسين الأداء. هذا المقال غطى كلاً من: إصلاح PostgreSQL كاملةM SK2حواسيب حافة البحث النصية (مصطلحات إختصاريّة, عبارات تقنية, غوغل- مشغلات نمطية) وتطبيق تحسينات الأداء الرئيسية MSC8 المخزنة, التحميل, تغطية الإحصائيات, ts_rank_cd).

تم تحقيق 30-50% بحث أسرع بينما تقلل ضغط قاعدة البيانات من خلال:

  • تصنيف كثافة الغطاء (ts_rank_cd) لجعل الموضوع أكثر relevance
  • ال caching اللغوي يزيل الاسئلة المتكررة
  • تعابير ILIKE المزدحمة لنظام SQL النظيف
  • تغطية المؤشرات التي تمكن من مسح المؤشر فقط
  • أزيلت أساس EF غير ضروري بما في ذلك

الفكرة الرئيسية: لا يوجد منهج واحد يتعامل مع كل الحالات. PostgreSQL FTS تفوق على تطابق كلمات المرور , البحث الدلالي يتعامل باسئلة نظرية , والتراجعات المستهدفة تأخذ في الإعتبار الحالات المتطرفة MSC4 طبقة التحليل النظيفة تربطها معاً M SK5 تتعامل مع المشغلين والمصطلحات التقنية قبل أن تصل إلى محرك البحث

البنية التحتية للبحث الدلالي تخدم أهدافاً مزدوجة:

  • المستخدم- يوجه البحث: يجمع كلمات رئيسية ومقارنة الدلالية لأفضل النتائج
  • استرجاع RAG: تعطي قوة محامي GPT مساعد الكتابة

المقالات الأخرى:

الوثائق الرسمية:

كل البرمجة المتاحة في blog's مخزن GitHub.

logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.