# साइट को ठीक करना's खोज:postgreSQL पूर्णM SK2पाठ खोज MSC3और जहाँ यह टूटता है

<!--category-- ASP.NET, PostgreSQL, Search, RRF -->
<datetime class="hidden">2026-01-14T12:00</datetime>

खोज उन विशेषताओं में से एक है जो सभी कम मानते हैं। *सैद्धांतिक रूप-से* सही लेकिन पाठ्य रूप से गलत

यह' also somethign है कि ' ने इस साइट पर बिगाड़ पैदा किया है क्योंकि यह' के शुरूआत से [ओपन सर्चQuery](/blog/textsearchingpt2), PostgreSQL पूर्ण पाठ खोज के साथ काम किया है, इसके साथ '\s फैशनी भेक्टर सामान लेकिन कभी भी सचमुच उससे खुश नहीं था **भ्रमित** मुझे विशेष रूप से अब मैं एक खोज उपकरण बना रहा हूँ [***सुदृढ़*आरएजी**](https://www.lucidrag.com) अच्छी तरह से मैंने सोचा कि मैं अंततः इसे ठीक करना चाहिए
क्या यह है या नहीं एक अन्य बात है

यह लेख नहीं है-' शून्य से एक खोज इंजिन का निर्माण करने के बारे में नहीं है।

**पूर्ववर्ती कार्यों पर निर्माण**: यह अनुच्छेद [अर्थात्मक खोज क्रियान्वयन](/blog/semantic-search-in-action) जिसने पारस्परिक रैंक फ्यूजन के साथ हाइब्रिड खोज जोड़ी।

सेमेटिक खोज अवसंरचना दो उद्देश्यों का काम करती है *और* के लिए पुनर्प्राप्ति परत प्रदान करता है [वकील जीपीटी](/blog/building-a-lawyer-gpt-for-your-blog-part1) RAG प्रणाली -एक लेखन सहायक जो साइट के उपयोग से नए पदों का प्रारूप करता है। [अधिवक्ता GPT का निर्माण](/blog/building-a-lawyer-gpt-for-your-blog-part3) एम्बेडिंग और भेक्टर खोज पर

## समस्याएं

### 1. खाली परिणाम अनियमित लेख दिखाए गए

जब एक खोज ने कोई परिणाम नहीं दिखाया, तो सिस्टम सहायक सुझावों के बजाय अनियमित पुराने लेख दिखा रहा था।

**द फिक्स**: परिवर्धित `BlogSearchService.HybridSearchWithPagingAsync()` पता लगाने के लिए जब खोज शून्य परिणाम लौटाता है और वापस पिछले पोस्टों को दिखाने के लिए नीचे आने वाले तिथि से क्रमबद्ध करने में गिर जाता है `NoMatchFound` फ्लैग को `BasePagingModel` यूआई एक उपयुक्त संदेश प्रदर्शित कर सकता है जैसे " कोई मिलान नहीं मिला

```csharp
// 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. एसcronyms Like

PostgreSQL के पूर्वनिर्धारित अंग्रेजी पाठ खोज कॉन्फ़िगरेशन में तकनीकी रूप से एक्रोनिमों को अनुक्रमित करता है, लेकिन सामान्यीकरण और समापन से छोटा होता है।

**द फिक्स**à¤à¥à¤°à¥à¤ `ILIKE`. यह इसे बदलने के बजाय पूर्ण पाठ खोज को संपूरित करता है।

```csharp
// 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}%"));
```

### 3. विशेष अक्षरों के साथ तकनीकी शर्तें विच्छेद खोज

के लिए खोजें असफल होंगी क्योंकि PostgreSQL की पाठ खोज पदवर्णक अवधि और हैश प्रतीकों को डिलिमिटर के रूप में व्यवहार करता है।

**द फिक्स**: एक बनाया गया `SearchQueryParser` जो सामान्य तकनीकी शब्दों को पहचानता है और उन्हें खोज योग्य संस्करणों से बदलता है

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

### प्रश्नों की तरह "ASP

पोस्टग्रेएसक्यूएल ने " और" को एक रोक शब्द के रूप में व्यवहार किया है तथा इसे खोजों से हटाता है।

**द फिक्स**: एक गूगल - शैली क्वेरी पारसर को लागू किया है जो stop शब्दों को कुशलता से नियंत्रित करता है और उन्नत खोज ऑपरेटरों का समर्थन करता है

## समाधान

### Google-Style खोज ऑपरेटर

मैंने एक कार्यान्वित किया `SearchQueryParser` वर्ग जो `:` के लिए समर्थन सहित प्रश्नों को पद वर्णन करता है

1. **उद्धरण वाक्यांश**: `"exact match"` - सही वाक्यांश के लिए खोजता है
2. **अपवर्जित शर्तें**: `-unwanted` - इस शब्द को समाहित परिणामों को छोड़ता है
3. **विल्डकार्ड**: `ASP*` मिलाएँ
4. **तकनीकी शर्तें**स्वचालित रूप से ह्यान्डल करता है

पदवर्णक क्वेरी को टोकनाइज करने के लिए एक संकलित रेगेक्स पैटर्न का उपयोग करता है

```csharp
[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 में परिवर्तित किया जाता है `to_tsquery` क्योंकि हम निर्मित वाक्य संरचना उत्पन्न कर रहे हैं `websearch_to_tsquery` क्योंकि हम पहले से ही ऑपरेटरों का विश्लेषण कर चुके हैं

```csharp
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`?**
> चूंकि यह अभी भी तकनीकी संदर्भों पर असफल है।

### उन्नत BuildSearchQuery

 `BuildSearchQuery` विधि को पूर्ण रूप से फिर से लिखा गया है पद वर्णन क्वेरी संरचना का उपयोग करने के लिए `baseQuery` भाषा के अनुसार पहले से ही फ़िल्टर करता है, तिथि शृंखला

```csharp
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" के साथ मिलाता है

### तकनीकी शर्तें

```
ASP.NET
```

ASP के बारे में लेख ढूंढता है

### वाक्यांश खोज

```
"semantic search"
```

✅ वस्तुओं में सही वाक्यांश खोजता है

### अपवर्जित शर्तें

```
ASP.NET -Core
```

à¤à¥à¤°à¥à¤

### विल्डकार्ड

```
ASP*
```

मिलान

### जटिल प्रश्न

```
"full text search" PostgreSQL -MySQL
```

✅ सही वाक्यांश के साथ आलेखों को खोजता है.

### पूर्व और बाद उदाहरण

**क्वेरी**: `ASP.NET and Alpine`

**पहले** टूटा

- एमएसके0एएसपीएमएसके1नेटएमएसक2में विभाजित होता है
- आरंभ शब्द के रूप में "and" हटाया
- परिणाम: केवल खोज के लिए "AlpineM SK2

**इसके बाद** स्थिर

- को "ASPM SK1NET" में बदल दिया गया
- उपयोगकर्ता क्वेरी उद्देश्य के भाग के रूप में intelligently preserved
- सामान्य रूप से खोजा गया
- परिणाम: ASP तथा Alpine दोनों के बारे में लेख पाता है

## आरआरएफ रैंकिंग इंटीग्रेशन

खोज प्रतिस्परिक रैंक फ्यूजन (RRF) के साथ एकीकृत करता है जैसा कि इस में लागू किया गया [पूर्व सेमेटिक खोज लेख](/blog/semantic-search-in-action#hybrid-search-with-reciprocal-rank-fusion). आरआरएफ यहाँ के लिए उपयोग किया जाता है *वरीयता*, रिकार्ड नहीं करता है।

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

आरआरएफ एल्गोरिथ्म का उपयोग करता है `1/(k+rank)` जहां k=60 कई स्रोतों से परिणामों को जोड़ने के लिए M SK1 तब boosts के लिए लागू करता है

- **श्रेणी मिलान**: +2.0
- **शीर्षक मिलान**: +1.0
- **ताजगी**: वर्ष के दौरान एक्सपोनेन्शल ह्रास

पूर्ण आरआरएफ क्रियान्वयन और हाइब्रिड खोज कैसे काम करता है [क्रिया में सांकेतिक खोज](/blog/semantic-search-in-action). embeddings और वेक्टर समानता में गहरे खोज के लिए [अधिवक्ता GPT का निर्माण](/blog/building-a-lawyer-gpt-for-your-blog-part3). एक ही मूल संरचना उपयोगकर्ता को दोनों शक्तियां प्रदान करता है

## तकनीकी वास्तुकला

### निर्भरता इंजेक्शन

नए घटक सेवाओं के रूप में पंजीकृत हैं

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

`SearchQueryParser` और `SearchRanker` एकलटन होते हैं क्योंकि वे stateless है `BlogSearchService` स्कॉप किया गया है क्योंकि यह डाटाबेस संदर्भ पहुँचता है

### क्वेरी फ्लो

1. **उपयोगकर्ता खोज क्वेरी प्रविष्ट करता है** खोज कंट्रोलर
2. **क्वेरी विश्लेषण** → SearchQueryParser संरचनात्मक घटकों में विभाजित करता है
3. **सेमेंटिक खोज (यदि सक्षम है** → ONNX सम्मिलित के साथ Qdrant भेक्टर डाटाबेस
4. **पोस्टग्रेएसक्यूएल पूरा -पाठ खोज** → BM25-आधारित शब्दकुञ्जी मिलान
5. **आरआरएफ संलयन** → दोनों परिणाम सेट को श्रेणी के साथ जोड़ता है
6. **कोई परिणाम नहीं** → हाल के पदों को सुझाव के रूप में लौटाता है

एक ही सेमेटिक खोज अवयव भी द्वारा उपयोग किया जाता है [वकील जीपीटी](/blog/building-a-lawyer-gpt-for-your-blog-part1) AI के लिए प्रासंगिक पिछली ब्लॉग पोस्टों को प्राप्त करने की प्रणाली [भाग 4](/blog/building-a-lawyer-gpt-for-your-blog-part4) इंजेक्शन पाइपलाइन के बारे में जानकारी के लिए

### डाटाबेस योजना

खोज पूर्वानुमानित पर निर्भर करता है `SearchVector` स्तंभ में `BlogPosts` तालिका

```sql
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 (Generalized Inverted Index) provides fast full

## निष्पादन विचार

### संक्षिप्ताक्षरों के लिए इलाइक क्यों है

जब `ILIKE` @item: inlistbox Adjective type

1. पूर्ण-पाठ खोज सामान्य बनाता है
2. संक्षिप्ताक्षर आमतौर पर छोटे हैं (≤6 अक्षरों), निष्पादन प्रभाव को सीमित करने के लिए
3. शर्त तभी जोड़ी जाती है जब आवश्यक हो (अक्षांशों को पहचाना गया

यह दृष्टिकोण लाखों पंक्तियों के बीच स्वैच्छिक उपस्ट्रिंग खोज पर मापन नहीं करेगा, लेकिन लक्षित लघुकवि के लिए वापसी यह

### पोस्टग्रेएसक्यूएल आवरण घनत्व रेटिंग (`ts_rank_cd`)

पोस्टग्रेएसक्यूएल पूरा के लिए दो रैंकिंग फ़ंक्शन्स प्रदान करता है

- `ts_rank`बुनियादी शब्द आवृत्ति
- `ts_rank_cd`कवर घनत्व रैंकिंग

हम उपयोग करते हैं `ts_rank_cd` क्योंकि यह प्रदान करता है **BM25-सदृश प्रासंगिकता** समय निकटता को ध्यान में रखते हुए

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

**क्यों `ts_rank_cd` बेहतर है**

मीट्रिक | `ts_rank` | `ts_rank_cd` |
|--------|-----------|--------------|
| **एल्गोरिथम** | सावधि आवृत्ति
| **बहुत से शब्द क्वेरी** | शर्तों को अलग से गणना करता है | पुरस्कार शर्तें एक साथ प्रकट होती हैं
| **उदाहरण** के साथ | अनुच्छेद1से अधिक गुण प्राप्त करता है |docker | " |50 |times scores high
| **निष्पादन** | तेजी से | मार्जिनally slower, अभी भी GIN सूचकांक को लेबरेज करता है
| **व्यवहार** साधारण गणना

यह एक है **त्वरित जीत अनुकूलन** 0 अनुप्रयोग के साथ बेहतर प्रासंगिकता रैंकिंग `SearchVector`.

**संदर्भ**

- [PostgreSQL ts_rank_cd दस्तावेज़](https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-RANKING)
- [ईएफ कोर रैंककोवरडैंसिटी](https://learn.microsoft.com/en-us/ef/core/providers/postgres/misc#full-text-search)

### अतिरिक्त निष्पादन अनुकूलन

खोज कार्यात्मकता को सुधारने के अलावा कई प्रमुख सुधार निष्पादन में सुधार करते हैं

#### भाषा कैशिंग

उपलब्ध भाषाएँ दुर्लभ रूप से बदलती हैं लेकिन प्रत्येक खोज अनुरोध पर क्वेरी की जाती है

```csharp
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);
```

**प्रभाव**: खोज अनुरोध प्रति डाटाबेस क्वेरी को समाप्त करता है

#### 2. बैच आईलिक क्वेरी

मूल कोड का प्रयोग `foreach` बहुविध WHERE खंडों को बनाने वाले लूप्स. अब एकल एक्सप्रेशन में बैच किया गया

```csharp
// 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}%")));
}
```

**प्रभाव**क्लीनर एसक्यूएल

#### सामान्य प्रश्नों के लिए 3. आवरण सूचकांक

आंशिक अनुक्रमणिका जोड़ी गई है INCLUDE स्तम्भों के साथ बार-बार अभिगम पैटर्न

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

**प्रभाव**सक्षम करता है [सिर्फ स्कैन करता है](https://www.postgresql.org/docs/current/indexes-index-only-scans.html) PostgreSQL को तालिका ढेर पहुँचने की जरूरत नहीं है

#### 4. हटाया अनावश्यक शामिल है

ईएफ कोर `Include()` पूर्ण नेविगेशन इकाइयों को लोड करता है. जहाँ केवल WHERE खंडों में प्रयुक्त नेविगेशन गुणों को हटाया जाता है

```csharp
// 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")
```

**प्रभाव**मेमोरी कमी

**संदर्भ**

- [PostgreSQL अनुक्रमणिका](https://www.postgresql.org/docs/current/indexes.html)
- [ईएफ कोर निष्पादन](https://learn.microsoft.com/en-us/ef/core/performance/)

### क्वेरी अनुकूलन रणनीति

खोज बनाता है जहाँ खंडों को क्रमशः उपयोग करते हुए [EF Core's एक्सप्रेशन ट्री संरचना](https://learn.microsoft.com/en-us/ef/core/querying/):

```csharp
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(...); }
```

यह एक उत्पन्न करता है **एकल अनुकूलित एसक्यूएल क्वेरी** बहुविध राउंड टाइप के बजाय

## निष्पादन सारांश

सभी optimizations का संकलित प्रभाव

अनुकूलन
|-------------|----------------|----------------|
भाषा कैशिंग
हटाएँ शामिल करें
बैच इलाइक
कवरिंग अनुक्रमणिका
| tsM SK1rank_cd | समान | बेहतर प्रासंगिकता
कैश फिक्स (मार्ग पैरामीज़

**कुल प्रत्याशित सुधार**: **30-50% तेज खोज** काफी कम डाटाबेस लोड के साथ

## सीखा गया पाठ

1. **Don't assume full-text search handles everything**: एक्रोनिम और विशेष अक्षरों जैसे किनारे के मामलों को विशेष व्यवहार की आवश्यकता होती है

2. **बहुविध दृष्टिकोणों को संयोजित करें**पाठ खोज (BM

3. **गूगल ने उपयोगकर्ताओं की अपेक्षाओं को आकार दिया**: उद्धरण वाक्यांशों को समर्थित करता है।

4. **सहायक अपवर्त उपलब्ध कराएँ**जब खोज असफल होती है तो

5. **पार्से**एक उचित क्वेरी पार्सर स्ट्रिंग परिचालनों की श्रृंखला से अधिक साफ और रख-रखाव करने योग्य है

6. **PostgreSQL लाईवरेज**उपयोग `ts_rank_cd` के बजाय `ts_rank` के लिए BM25-सदृश प्रासंगिकता. आवरण घनत्व रैंकिंग शब्द समीपता को मानता है | - | एक त्वरित जीत जो शून्य अनुप्रयोग के साथ परिणाम गुणवत्ता में सुधार करता है

7. **अनुकूलन से पहले प्रोफ़ाइल**: त्रुटियों को स्पष्ट करता है।

8. **बैच डाटाबेस ऑपरेशन**: बहुविध `foreach` लूप अलग अलग WHERE खंड बनाने के लिए उपoptimal SQL उत्पन्न करता है `Any()` या `All()` एकल एक्सप्रेशन में बैच करने के लिए

## भावी संवर्धन

भविष्य के लिए संभावित सुधार

**पुनःप्राप्ति सुधार**:

- **अस्पष्ट मिलान**टाइपो सहिष्णुता के लिए : लेवेन्सटेन दूरी
- **संज्ञा विस्तार**ब्लॉग पोस्ट

**पद वर्णन संवर्धन**:

- **श्रेणी फिल्टरिंग**: `category:ASP.NET` प्रचालक
- **तिथि शृंखला**: `after:2025-01-01` प्रचालक

**रैंकिंग परिमार्जन**:

- **परिणाम हाइलाइटिंग**: परिणाम में पाठ के संगत भाग दिखाएँ
- **ट्रैकिंग के माध्यम से क्लिक करें**: रैंकिंग में सुधार के लिए उपयोगकर्ता व्यवहार से सीखें

**प्रेक्षणशीलता**:

- **खोज विश्लेषण**: लोकप्रिय क्वेरी को ट्रैक करें और अंतरों की पहचान करने के लिए असफल खोज

## निष्कर्ष

निर्माण उत्पादन-श्रेणी खोज को किनारा केसों को स्थिर करने की आवश्यकता होती है **और** निष्पादन को अनुकूलित करना. इस लेख में दोनों शामिल हैं। `ts_rank_cd`).

क्रियान्वयन प्राप्त करता है **30-50% तेज खोज** के माध्यम से डाटाबेस लोड को कम करते हुए

- आवरण घनत्व रैंकिंग (`ts_rank_cd`बेहतर प्रासंगिकता के लिए )
- भाषा कैशिंग, बार-बार पूछे जाने वाले प्रश्नों को समाप्त करता है
- साफ SQL के लिए बैच आईलिक एक्सप्रेशन
- अनुक्रमणिका सक्षम करने के लिए आंकड़े का आवरण
- हटाए गए अनावश्यक एफ कोर में शामिल है

प्रमुख अंतर्दृष्टि: कोई एकल दृष्टिकोण सभी केसों को नियंत्रित करता है।

सांकेतिक खोज अवसंरचना दो उद्देश्यों की सेवा करती है

- **उपयोगकर्ता-फ़ॉक्सिंग खोज**: बेहतर परिणाम के लिए शब्दकुञ्जी और अर्थात्मक मिलान को संयोजित करता है
- **आरएजी पुनःप्राप्ति**: पावर [वकील जीपीटी](/blog/building-a-lawyer-gpt-for-your-blog-part1) लेखन सहायक

**संबंधित लेख:**

- [क्रिया में सांकेतिक खोज](/blog/semantic-search-in-action) आरआरएफ के साथ हाइब्रिड खोज
- [अधिवक्ता GPT का निर्माण](/blog/building-a-lawyer-gpt-for-your-blog-part3) - एम्बेडिंग्स
- [अधिवक्ता GPT का निर्माण](/blog/building-a-lawyer-gpt-for-your-blog-part4) - इंजेक्शन पाइपलाइन

**आधिकारिक दस्तावेज़**

- [पोस्टग्रेएसक्यूएल पूर्ण](https://www.postgresql.org/docs/current/textsearch.html)
- [PostgreSQL अनुक्रमणिका](https://www.postgresql.org/docs/current/indexes.html)
- [ईएफ कोर निष्पादन](https://learn.microsoft.com/en-us/ef/core/performance/)
- [ईएफ कोर एनपीजीएसक्यूएल प्रदाता](https://www.npgsql.org/efcore/index.html)

सभी कोड उपलब्ध है [ब्लॉग's GitHub रिपोजिटरी](https://github.com/scottgal/mostlylucidweb).