Back to "लागू करनेवालों के लिए RAG: क्रिया में सेप्टिक खोजQuery"

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

AI-Article Alpine.js ASP.NET HTMX Hybrid Search RAG Semantic Search

लागू करनेवालों के लिए RAG: क्रिया में सेप्टिक खोजQuery

Wednesday, 24 December 2025

परिचय

RAG वस्तुओं का सबसे बड़ा भाग: यह पार्ट ४बी - खोज विशेषताएँ और यूआई है:

में पार्ट 4a, हमने आधार बनाया: NNXMing और Qund सदिश भंडार. अब चलो एक के साथ काम करने के लिए इसे डाल दिया है वास्तविक खोज यूआई - जिनमें से किसी ने भी प्रकार का स्वतः सामना किया है, ग्रोन खोजकिक + पूर्ण पाठ, और ज्यादा फ़िल्टरिंग शामिल है.

इस लेख में इस ब्लॉग पर आपकी खोज के अनुभव दिए गए हैं ।

टाइप हेड खोज अनुभव

इस साइट के शीर्ष पर खोज बक्से में तत्काल खोज परिणाम मिलते हैं. यहाँ है कि यह कैसे काम करता है:

sequenceDiagram
    participant U as User
    participant A as Alpine.js
    participant API as SearchApi
    participant H as HybridSearch
    participant S as Semantic Search
    participant P as PostgreSQL

    U->>A: Types "docker"
    A->>A: Debounce 300ms
    A->>API: GET /api/search/docker
    API->>H: HybridSearchAsync("docker")
    par Parallel Search
        H->>S: SearchAsync("docker", 20)
        H->>P: GetSearchResultForComplete("docker")
    end
    S-->>H: Semantic results (by meaning)
    P-->>H: Full-text results (by keywords)
    H->>H: Apply RRF scoring
    H-->>API: Combined results
    API-->>A: JSON results
    A->>U: Display dropdown

आजीवन घटक

खोज पेटी उपयोग यू. एस. बिना भारी जावास्क्रिप्ट फ्रेमवर्क के प्रतिक्रिया के यूआई के लिए. यहाँ अवयव है:

export function typeahead() {
    return {
        query: '',
        results: [],
        highlightedIndex: -1, // Tracks keyboard navigation

        search() {
            // Minimum 2 characters to trigger search
            if (this.query.length < 2) {
                this.results = [];
                this.highlightedIndex = -1;
                return;
            }

            fetch(`/api/search/${encodeURIComponent(this.query)}`, {
                method: 'GET',
                headers: { 'Content-Type': 'application/json' }
            })
            .then(response => {
                if (response.ok) return response.json();
                return Promise.reject(response);
            })
            .then(data => {
                this.results = data;
                this.highlightedIndex = -1;
                // Process HTMX attributes in results
                this.$nextTick(() => {
                    htmx.process(document.getElementById('searchresults'));
                });
            })
            .catch((response) => {
                console.log("Error fetching search results");
            });
        },

        // Keyboard navigation
        moveDown() {
            if (this.highlightedIndex < this.results.length - 1) {
                this.highlightedIndex++;
            }
        },

        moveUp() {
            if (this.highlightedIndex > 0) {
                this.highlightedIndex--;
            }
        },

        selectHighlighted() {
            if (this.highlightedIndex >= 0 && this.highlightedIndex < this.results.length) {
                this.selectResult(this.highlightedIndex);
            }
        },

        selectResult(selectedIndex) {
            // Click the HTMX link to navigate
            let links = document.querySelectorAll('#searchresults a');
            links[selectedIndex].click();
            this.results = [];
            this.highlightedIndex = -1;
            this.query = '';
        }
    }
}

कुंजी फीचर:

  1. आरईएसडी इनपुट: 300ms देरी सर्वर के नक़ल करने में बाधा
  2. न्यूनतम लम्बाई: कम से कम 2 अक्षर जरूरी
  3. कुंजीपट नेविगेशनपहुँच के लिए तीर कुंजी + भरें
  4. एचएसएमएक्स संयोजन: परिणाम मृदु नेविगेशन के लिए HMMX प्रयोग करें

ढूंढना दिखाएँ (S)

<div x-data="window.mostlylucid.typeahead()"
     class="relative"
     x-on:click.outside="results = []">

    <label class="input input-sm bg-white dark:bg-custom-dark-bg input-bordered flex items-center gap-2">
        <input
            type="text"
            x-model="query"
            x-on:input.debounce.300ms="search"
            x-on:keydown.down.prevent="moveDown"
            x-on:keydown.up.prevent="moveUp"
            x-on:keydown.enter.prevent="selectHighlighted"
            placeholder="Search..."
            class="border-0 grow input-sm text-black dark:text-white bg-transparent w-full"/>
        <i class="bx bx-search"></i>
    </label>

    <!-- Dropdown Results -->
    <ul x-show="results.length > 0"
        id="searchresults"
        class="absolute z-10 my-2 w-full bg-white dark:bg-custom-dark-bg border rounded-lg shadow-lg">
        <template x-for="(result, index) in results" :key="result.slug">
            <li :class="{'bg-blue-light dark:bg-blue-dark': index === highlightedIndex}"
                class="cursor-pointer text-sm p-2 m-2 hover:bg-blue-light dark:hover:bg-blue-dark">
                <a hx-boost="true"
                   hx-target="#contentcontainer"
                   hx-swap="innerHTML show:window:top"
                   :href="result.url"
                   x-text="result.title"></a>
            </li>
        </template>
    </ul>
</div>

क्यों x-on:click.outside? स्वतः सहेजने के लिए ड्रापिंग बन्द करता है - मानक यूएक्स पैटर्न के लिए.

खोज एपीआई

वह /api/search/{query} अंत की शक्तियाँ टाइप हेड. यहाँ नियंत्रक है:

[ApiController]
[Route("api")]
public class SearchApi(
    BlogSearchService searchService,
    UmamiBackgroundSender umamiBackgroundSender,
    ISemanticSearchService semanticSearchService,
    SemanticSearchConfig semanticSearchConfig) : ControllerBase
{
    private const int RrfConstant = 60; // Reciprocal Rank Fusion constant

    [HttpGet]
    [Route("search/{query}")]
    [OutputCache(Duration = 3600, VaryByQueryKeys = new[] { "query" })]
    public async Task<Results<JsonHttpResult<List<SearchResults>>, BadRequest<string>>> Search(string query)
    {
        using var activity = Log.Logger.StartActivity("Search {query}", query);
        try
        {
            var host = Request.Host.Value;
            List<SearchResults> output;

            // Use hybrid search if semantic search is enabled
            if (semanticSearchConfig.Enabled)
            {
                output = await HybridSearchAsync(query, host);
            }
            else
            {
                // Fallback to full-text search only
                output = await FullTextSearchAsync(query, host);
            }

            // Track search event for analytics
            var encodedQuery = HttpUtility.UrlEncode(query);
            await umamiBackgroundSender.Track("searchEvent", new UmamiEventData { { "query", encodedQuery } });

            return TypedResults.Json(output);
        }
        catch (Exception e)
        {
            Log.Error(e, "Error in search");
            return TypedResults.BadRequest("Error in search");
        }
    }
}

ज़रूरी डिज़ाइन:

  1. विशेषता फ्लैग: semanticSearchConfig.Enabled आपको टॉगल करता है कि
  2. आउटपुट कैशिंग: 1 घंटे कैश सर्वर लोड करता है सामान्य दाँतों के लिए
  3. विश्लेषणशीलता की खोज: प्रत्येक खोज पर नज़र रखी जाती है (help उपयोक्ता के बर्ताव को समझने में)
  4. अनुग्रहपूर्ण कमीयदि चेकिक खोज असफल हो तो एसक्यूएल को वापस गिरता है

हाइब्रीड ढूंढने के लिए छोटे सेमीफ फ़्यूशन के साथ

वास्तविक जादू है ओपन- पीजीपी खोज - उनको पूरी तरह से मिलाने के लिए एक-दूसरे से जुड़े हुए और पूरे पाठ परिणाम. हम छोटे से छोटे आकार का उपयोग करते हैं.

ऐसा क्यों?

अलग - अलग तरह की खोज के पास अलग - अलग ताकत होती है:

कठिन खोज प्रकार |------------|-----------|------------| | सिलिकिक Syynyyyyyyms, मतलब, धारणाएँ स्वाभाविक रूप से सही वाक्यांशों को चूक सकती हैं | पूर्ण पाठ IMPRICT बीजशब्द, तकनीकी संदर्भCLLLLLLLLLLLLLLLLLLLLL

उदाहरण: "रक्षा" के लिए खोज कर रहा है

  • सेंसिक पाते हैं: "कंकर शिक्षण पाठ", "Klerrernets" (सेप्टुआजिक धारणाओं)
  • पूर्ण पाठ प्राप्त करता है: (c)
  • Hybd दोनों का सबसे अच्छा हो जाता है!

RRF एलागरिथम

flowchart TB
    subgraph Semantic[Semantic Results]
        S1[Docker Containers - 0.92]
        S2[Kubernetes Basics - 0.87]
        S3[Container Security - 0.81]
    end

    subgraph FullText[Full-Text Results]
        F1[Container Security - rank 1]
        F2[Docker Containers - rank 2]
        F3[CI/CD Pipelines - rank 3]
    end

    subgraph RRF[RRF Scores]
        R1[Container Security = 0.0327]
        R2[Docker Containers = 0.0325]
        R3[Kubernetes Basics = 0.0161]
        R4[CI/CD Pipelines = 0.0159]
    end

    subgraph Final[Final Ranking]
        O1[Container Security]
        O2[Docker Containers]
        O3[Kubernetes Basics]
        O4[CI/CD Pipelines]
    end

    S1 --> R2
    S2 --> R3
    S3 --> R1
    F1 --> R1
    F2 --> R2
    F3 --> R4
    R1 --> O1
    R2 --> O2
    R3 --> O3
    R4 --> O4

सूत्र score = Σ(1 / (k + rank))

कहाँ:

  • k = 60 (ऊपर से आगे बढ़ने के लिए तेजी से आगे)
  • rank = उस खोज विधि में स्थिति (1- विस्तृत)

क्यों RRF काम करता है:

  • परिणाम जो भीतर प्रकट होते हैं दोनों स्रोत अंक उच्च
  • कोई भी स्रोत ऊपर कर सकता है
  • कोई जटिल फ़्लिंग आवश्यक नहीं

कार्यान्वयन

private async Task<List<SearchResults>> HybridSearchAsync(string query, string host)
{
    // Run both searches in parallel
    var fullTextTask = GetFullTextResultsAsync(query);
    var semanticTask = semanticSearchService.SearchAsync(query, limit: 20);

    await Task.WhenAll(fullTextTask, semanticTask);

    var fullTextResults = await fullTextTask;
    var semanticResults = await semanticTask;

    // Apply Reciprocal Rank Fusion to combine results
    var rrfScores = new Dictionary<string, (double Score, string Title, string Slug)>();

    // Score full-text results
    for (int i = 0; i < fullTextResults.Count; i++)
    {
        var (title, slug) = fullTextResults[i];
        var key = slug.ToLowerInvariant();
        var rrfScore = 1.0 / (RrfConstant + i + 1);

        if (rrfScores.TryGetValue(key, out var existing))
        {
            rrfScores[key] = (existing.Score + rrfScore, title, slug);
        }
        else
        {
            rrfScores[key] = (rrfScore, title, slug);
        }
    }

    // Score semantic results
    for (int i = 0; i < semanticResults.Count; i++)
    {
        var result = semanticResults[i];
        var key = result.Slug.ToLowerInvariant();
        var rrfScore = 1.0 / (RrfConstant + i + 1);

        if (rrfScores.TryGetValue(key, out var existing))
        {
            rrfScores[key] = (existing.Score + rrfScore, existing.Title, existing.Slug);
        }
        else
        {
            rrfScores[key] = (rrfScore, result.Title, result.Slug);
        }
    }

    // Sort by combined RRF score and return top results
    return rrfScores.Values
        .OrderByDescending(x => x.Score)
        .Take(15)
        .Select(x => new SearchResults(
            x.Title.Trim(),
            x.Slug,
            Url.ActionLink("Show", "Blog", new { x.Slug }, "https", host)))
        .ToList();
}

कुंजी कार्यान्वयन विवरण:

  1. समानांतर चलाना: दोनों का पता एक साथ चलता है (एक साथ)Task.WhenAll)
  2. केस सेंसिटिव डीपीप: स्फ्यूग के साथ सामान्य ToLowerInvariant()
  3. अंक Accumदोनों स्रोतों में एक ही पोस्ट को कई बार जोड़ा जाता है
  4. ऊपरी 15 परिणाम: भारी नहीं, क़िस्म के लिए काफी है

पूर्ण पाठ खोज फालबैक

जब Caditic खोज अक्षम है या असफल रहा है, हम पूर्ण पाठ खोज में वापस गिर जाते हैं.

क्वैरी हैंडलिंग

पूर्ण पाठ खोज दो मामलों को अलग से हैंडल करता है:

private async Task<List<(string Title, string Slug)>> GetFullTextResultsAsync(string query)
{
    if (!query.Contains(' '))
        return await searchService.GetSearchResultForComplete(query);  // Wildcard
    else
        return await searchService.GetSearchResultForQuery(query);     // Web search
}

एक शब्द (kor"): कार्ड उपसर्ग खोज का प्रयोग करें docker:* अनेक शब्द ("kolans") : महाजोंग के वेब सर्च सिंटेक्स का प्रयोग करें

एसक्यूएल क्वाटरर्स

// Single word with wildcard
private IQueryable<BlogPostEntity> QueryForWildCard(string query)
{
    return context.BlogPosts
        .Include(x => x.Categories)
        .Include(x => x.LanguageEntity)
        .AsNoTracking()
        .Where(x =>
            !x.IsHidden
            && (x.ScheduledPublishDate == null || x.ScheduledPublishDate <= now)
            && (x.SearchVector.Matches(EF.Functions.ToTsQuery("english", query + ":*"))
                || x.Categories.Any(c =>
                    EF.Functions.ToTsVector("english", c.Name)
                        .Matches(EF.Functions.ToTsQuery("english", query + ":*"))))
            && x.LanguageEntity.Name == "en")
        .OrderByDescending(x =>
            x.SearchVector.Rank(EF.Functions.ToTsQuery("english", query + ":*")));
}

// Multiple words with web search
private IQueryable<BlogPostEntity> QueryForSpaces(string processedQuery)
{
    return context.BlogPosts
        .Where(x =>
            x.SearchVector.Matches(EF.Functions.WebSearchToTsQuery("english", processedQuery))
            || x.Categories.Any(c =>
                EF.Functions.ToTsVector("english", c.Name)
                    .Matches(EF.Functions.WebSearchToTsQuery("english", processedQuery))))
        .OrderByDescending(x =>
            x.SearchVector.Rank(EF.Functions.WebSearchToTsQuery("english", processedQuery)));
}

क्यों WebSearchToTsQuery? यह प्राकृतिक भाषा को गूगल की तरह संभालता है:

  • "docker containers" ✔ दोनों शब्दों की जाँच कीजिए
  • docker OR kubernetes get बूलियन OR
  • docker -compose _FAQ( case") को अलग करता है

संपूर्ण पाठ खोज पर अधिक के लिए, देखें पोस्ट- धर्म के साथ पूरा पाठ खोज रहा है.

पूरा खोज पृष्ठ

टाइप्ट के बाद, वहाँ एक पूर्ण खोज परिणाम है फिल्टरों के साथ विस्तृत फिल्टरों के साथ:

flowchart LR
    subgraph SearchPage[Search Page]
        A[Query Input] --> B{Filters}
        B --> C[Language Filter]
        B --> D[Date Range Filter]
        C --> E[Search Results]
        D --> E
        E --> F[Paginated List]
    end

    style A stroke:#10b981,stroke-width:2px
    style B stroke:#6366f1,stroke-width:2px
    style E stroke:#ec4899,stroke-width:2px
    style F stroke:#8b5cf6,stroke-width:2px

खोज नियंत्रक

[Route("search")]
public class SearchController(
    BaseControllerService baseControllerService,
    BlogSearchService searchService,
    ISemanticSearchService semanticSearchService,
    ILogger<SearchController> logger)
    : BaseController(baseControllerService, logger)
{
    [HttpGet]
    [Route("")]
    [OutputCache(Duration = 3600, VaryByQueryKeys = new[] { "query", "page", "pageSize", "language", "dateRange", "startDate", "endDate" })]
    public async Task<IActionResult> Search(
        string? query,
        int page = 1,
        int pageSize = 10,
        string? language = null,
        DateRangeOption dateRange = DateRangeOption.AllTime,
        DateTime? startDate = null,
        DateTime? endDate = null,
        [FromHeader] bool pagerequest = false)
    {
        // Calculate date range based on option
        var (calculatedStartDate, calculatedEndDate) = CalculateDateRange(dateRange, startDate, endDate);

        // Get available languages for the filter dropdown
        var availableLanguages = await searchService.GetAvailableLanguagesAsync();

        if (string.IsNullOrEmpty(query?.Trim()))
        {
            var emptyModel = new SearchResultsModel { /* ... */ };
            if (Request.IsHtmx()) return PartialView("SearchResults", emptyModel);
            return View("SearchResults", emptyModel);
        }

        var searchResults = await searchService.HybridSearchWithPagingAsync(
            query,
            language,
            calculatedStartDate,
            calculatedEndDate,
            page,
            pageSize);

        // Build response model...
        if (pagerequest && Request.IsHtmx())
            return PartialView("_SearchResultsPartial", searchModel.SearchResults);
        if (Request.IsHtmx())
            return PartialView("SearchResults", searchModel);
        return View("SearchResults", searchModel);
    }
}

सीमा विकल्प

public enum DateRangeOption
{
    AllTime,
    LastWeek,
    LastMonth,
    LastYear,
    Custom
}

private static (DateTime? StartDate, DateTime? EndDate) CalculateDateRange(
    DateRangeOption dateRange, DateTime? startDate, DateTime? endDate)
{
    var now = DateTime.UtcNow;
    return dateRange switch
    {
        DateRangeOption.LastWeek => (now.AddDays(-7), now),
        DateRangeOption.LastMonth => (now.AddMonths(-1), now),
        DateRangeOption.LastYear => (now.AddYears(-1), now),
        DateRangeOption.Custom => (startDate, endDate),
        _ => (null, null) // AllTime - no date filter
    };
}

ला zy लोड के साथ संबंधित पोस्ट

प्रत्येक ब्लॉग पोस्ट में ऐसे ही पोस्ट दिखाए गए हैं जैसे कि कच्चे हुए स्तम्भों में. यह आलसी लोड करने के लिए HM3X प्रयोग करता है:

<!-- In blog post view -->
<div class="print:hidden"
     hx-get="/search/related/@Model.Slug/@Model.Language"
     hx-trigger="load delay:500ms"
     hx-swap="innerHTML">
    <!-- Loading placeholder -->
    <div class="mt-8 mb-8 text-center opacity-50">
        <span class="loading loading-spinner loading-md"></span>
        <p class="text-sm mt-2">Finding related posts...</p>
    </div>
</div>

500 बजे देर क्यों करें? मुख्य सामग्री पहले लोड होती है, फिर पृष्ठभूमि में पोस्टों के लोड होते हैं. उपयोक्ता तत्काल सामग्री को देखते हैं.

संबंधित पोस्ट अंतपाइंट

[HttpGet]
[Route("related/{slug}/{language}")]
[OutputCache(Duration = 7200, VaryByRouteValueNames = new[] {"slug", "language"})]
public async Task<IActionResult> RelatedPosts(string slug, string language, int limit = 5)
{
    var results = await semanticSearchService.GetRelatedPostsAsync(slug, language, limit);

    if (Request.IsHtmx())
    {
        return PartialView("_RelatedPosts", results);
    }

    return Json(results);
}

2 घंटे कैश: संबंधित पोस्टों में अकसर परिवर्तन नहीं होते, तो झगड़ालू क्लर्किंग सुरक्षित है.

सम्बन्धित पोस्ट अवयव

छोटे से छोटे - छोटे घटकों के साथ घटकर बन्द किया जा रहा है जिसमें समानता अंक दिखाए जाते हैं:

@model List<SearchResult>

@if (Model != null && Model.Any())
{
    <div class="mt-8 mb-8">
        <div class="collapse collapse-arrow bg-base-200">
            <input type="checkbox" class="peer" />
            <div class="collapse-title text-xl font-medium">
                <i class='bx bx-brain text-2xl mr-2'></i>
                Related Posts
                <span class="badge badge-secondary badge-sm ml-2">@Model.Count</span>
            </div>
            <div class="collapse-content">
                <div class="divider mt-0"></div>
                <div class="space-y-2">
                    @foreach (var post in Model)
                    {
                        <div class="card bg-base-100 shadow-sm hover:shadow-md transition-shadow">
                            <div class="card-body p-4">
                                <div class="flex items-start justify-between">
                                    <div class="flex-1">
                                        <a hx-boost="true"
                                           hx-target="#contentcontainer"
                                           asp-action="Show"
                                           asp-controller="Blog"
                                           asp-route-slug="@post.Slug"
                                           asp-route-language="@post.Language"
                                           class="card-title text-base hover:text-secondary">
                                            @post.Title
                                        </a>

                                        @if (post.Categories?.Any() == true)
                                        {
                                            <div class="flex flex-wrap gap-1 mt-2">
                                                @foreach (var category in post.Categories.Take(3))
                                                {
                                                    <span class="badge badge-outline badge-sm">@category</span>
                                                }
                                            </div>
                                        }

                                        <div class="flex items-center gap-3 mt-2 text-sm opacity-70">
                                            <span>
                                                <i class='bx bx-calendar'></i>
                                                @post.PublishedDate.ToString("MMM dd, yyyy")
                                            </span>
                                            <span>
                                                <i class='bx bx-planet'></i>
                                                @post.Language.ToUpper()
                                            </span>
                                        </div>
                                    </div>

                                    <!-- Similarity Score -->
                                    <div class="flex flex-col items-end ml-4">
                                        <div class="radial-progress text-primary text-xs"
                                             style="--value:@(post.Score * 100); --size:3rem; --thickness:3px;"
                                             role="progressbar">
                                            @((post.Score * 100).ToString("F0"))%
                                        </div>
                                        <span class="text-xs opacity-60 mt-1">similarity</span>
                                    </div>
                                </div>
                            </div>
                        </div>
                    }
                </div>
            </div>
        </div>
    </div>
}

सम्पूर्ण प्रगति समानता को प्रतिशत के रूप में दिखाता है (0- 100%), उपभोक्ताओं को यह समझने में मदद करता है कि हर पोस्ट से कैसे सम्बन्धित है.

एपीआई संदर्भ

टाइप हेड खोज

GET /api/search/{query}

SWECPECPE (सेटलमेंट% 2) |-----------|------|-------------| | query साइबेस स्ट्रिंग (path)

अनुक्रिया: List<SearchResults>

[
  {
    "title": "Docker Containers Explained",
    "slug": "docker-containers",
    "url": "https://example.com/blog/docker-containers"
  }
]

कैशिंग: 1 घंटे, क्वैरी द्वारा अलग-अलग

मेटा डाटा खोजQuery

GET /search/semantic?query={query}&limit={limit}

SECONPE (सेटलमेंट) प्रकार ( बहकाता है) |-----------|------|---------|-------------| | query Libisofs जरूरी खोज मद जिसपर विस्तार के लिए जरूरी है | limit गुज़र गए इंच 10 मि. बा.

अनुक्रिया: List<SearchResult> समानता अंक सहित

संबंधित पोस्ट

GET /search/related/{slug}/{language}?limit={limit}

SECONPE (सेटलमेंट) प्रकार ( बहकाता है) |-----------|------|---------|-------------| | slug IMTAL स्ट्रिंग जरूरी ब्लॉग पोस्ट lulush (l) | language एनटीएल स्ट्रिंग की आवश्यकता है शख़्स भाषा कोड (en, es, आदि) | limit औट इनहिट 5 मिण्डल अधिकतम से संबंधित पोस्ट- पोस्ट

अनुक्रिया: List<SearchResult> समानता द्वारा विभाजित करें

कैशिंग: 2 घंटे, अलग - अलग भाषा और अलग - अलग तरीके से

फ़िल्टरों के साथ पूर्ण ढूंढें

GET /search?query={query}&page={page}&pageSize={pageSize}&language={language}&dateRange={dateRange}&startDate={startDate}&endDate={endDate}

SECONPE (सेटलमेंट) प्रकार ( बहकाता है) |-----------|------|---------|-------------| | query Libisofs जरूरी खोज मद जिसपर विस्तार के लिए जरूरी है | page गीत- सूची | pageSize सन 2002- 2006 में 10अनक़रीब ही बढ़िया नतीजे निकलते हैं | language INBLLLKNNT OLON OGENK फ़िल्टर जिन पर भाषा लानत की जा सकती है | dateRange 56ELKTATELAT सारे समय, अंतिम वेक, अंतिम घंटे, अंतिम वर्ष, मनपसंद | startDate IMTANT तिथि नल प्रारंभ तिथि (तिथि) के साथ ( date- rowase= मनपसंद) | endDate IMTAL तिथिTEND तिथि (तिथिase= मनपसंद)

परफ़ॉर्मेंस हार्डवेयर्स

कैश प्लान किया जा रहा है

// Typeahead - 1 hour (queries are repeated often)
[OutputCache(Duration = 3600, VaryByQueryKeys = new[] { "query" })]

// Related posts - 2 hours (rarely change)
[OutputCache(Duration = 7200, VaryByRouteValueNames = new[] {"slug", "language"})]

// Full search - 1 hour (many filter combinations)
[OutputCache(Duration = 3600, VaryByQueryKeys = new[] { "query", "page", "pageSize", "language", "dateRange", "startDate", "endDate" })]

डिम्बियाजिंग

हमेशा प्रयोक्ता इनपुट को न्यूनतम एपीआई कॉल को रोकने के लिए देते हैं:

x-on:input.debounce.300ms="search"

300ms अच्छा संतुलन है - तेज प्रतिक्रिया महसूस करने के लिए पर्याप्त है, सर्वर लोड कम करने के लिए पर्याप्त धीमी गति से.

zy लोड किया जा रहा है

HMAX का प्रयोग करें load delay: विरोधी सामग्री के लिए ट्रिगरः

hx-trigger="load delay:500ms"

यह निश्‍चित करता है कि मुख्य वस्तु द्वितीय सामग्री बोझ उठाने से पहले दिखाई देती है ।

अगला क्या है

इस लेख में इस लेख पर परदा डाला गया खोज अनुभव - कैसे उपभोक्ताों की खोज के साथ व्यवहार करते हैं. उत्पादन तैनात जिसमें स्वचालित निर्देशिका तथा पृष्ठभूमि सेवा शामिल हैं, आगे भी जारी रखें:

पार्ट 5: Hybd खोज स्वचलित किया जा रहा है - उत्पादीकरण पैटर्न:

  • वास्तविक समय इंडेक्सिंग के लिए फ़ाइल तंत्र- तंत्र मॉनीटर
  • स्टार्टअप इंडेक्सिंग के लिए पृष्ठभूमि सेवा
  • वृद्धि अद्यतन के लिए विषयवस्तु का पता लगाया गया हैName

संसाधन

संबंधित आलेख

तकनालॉज़ी उपयोग में

कोड पूरा करें

सभी कोड इस पर उपलब्ध: gdyb.com/sek/ allyptib

  • Mostlylucid/API/SearchApi.cs - टाइप हेड एपीआई
  • Mostlylucid/Controllers/SearchController.cs - पूरा खोज पृष्ठ
  • Mostlylucid.Services/Blog/BlogSearchService.cs - हाइब्रिड खोज तर्क
  • Mostlylucid/src/js/typeahead.js - एक आजीवन घटक
logo

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