You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Django+Haystack实现用户输入时的搜索建议咨询

Got it, let's tackle adding search suggestions for your MainData model with your specific tech stack. I'll walk you through each step clearly, since you're using Django 1.11.8, Haystack 2.7.0, Solr 6.6.3, and Python 3.

Step 1: Configure Solr to Support Suggestions

First, we need to set up Solr's suggestion (spellcheck) component, since that's where the heavy lifting for autocomplete happens.

Update Solr's Managed Schema

Open your Solr core's managed-schema file (usually in solr/your_core/conf/) and add these configurations:

<!-- Field type optimized for suggestions (handles partial matches) -->
<fieldType name="text_suggest" class="solr.TextField" positionIncrementGap="100">
  <analyzer type="index">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="20"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

<!-- Dedicated field to store suggestion data -->
<field name="suggest" type="text_suggest" indexed="true" stored="false" multiValued="true"/>

<!-- Copy your MainData's title field into the suggest field -->
<copyField source="title" dest="suggest"/>

Configure Solr's Request Handler and Spellcheck Component

Next, edit solrconfig.xml in the same conf folder to add the suggestion endpoint:

<!-- Request handler to serve suggestions -->
<requestHandler name="/suggest" class="solr.SearchHandler">
  <lst name="defaults">
    <str name="echoParams">explicit</str>
    <str name="df">suggest</str>
    <str name="spellcheck">true</str>
    <str name="spellcheck.dictionary">suggestDict</str>
    <str name="spellcheck.onlyMorePopular">true</str>
    <str name="spellcheck.count">10</str>
    <str name="spellcheck.collate">false</str>
  </lst>
  <arr name="components">
    <str>spellcheck</str>
  </arr>
</requestHandler>

<!-- Spellcheck dictionary tied to our suggest field -->
<searchComponent name="spellcheck" class="solr.SpellCheckComponent">
  <lst name="spellchecker">
    <str name="name">suggestDict</str>
    <str name="classname">org.apache.solr.spelling.suggest.Suggester</str>
    <str name="lookupImpl">org.apache.solr.spelling.suggest.tst.TSTLookup</str>
    <str name="field">suggest</str>
    <float name="threshold">0.001</float>
    <str name="buildOnCommit">true</str>
  </lst>
</searchComponent>

Restart Solr after making these changes—this ensures the new configurations take effect.

Step 2: Set Up Haystack Index for MainData

Make sure your Haystack index is properly configured to index the title field, which we'll use for suggestions.

Create the Search Index

In your app's search_indexes.py file (create it if it doesn't exist):

from haystack import indexes
from .models import MainData

class MainDataIndex(indexes.SearchIndex, indexes.Indexable):
    # Primary document field (required by Haystack)
    text = indexes.CharField(document=True, use_template=True)
    # Index the title field explicitly
    title = indexes.CharField(model_attr='title')

    def get_model(self):
        return MainData

    def index_queryset(self, using=None):
        # Exclude entries with empty titles to avoid useless suggestions
        return self.get_model().objects.exclude(title__isnull=True).exclude(title__exact='')

Create the Index Template

Create a template at templates/search/indexes/your_app_name/maindata_text.txt (replace your_app_name with your actual app name):

{{ object.title }}

Rebuild the Index

Run this command to reindex all your MainData entries so the new suggest field gets populated:

python manage.py rebuild_index
Step 3: Build a Django View to Serve Suggestions

Haystack 2.7.0 doesn't have out-of-the-box support for Solr suggestions, so we'll use pysolr directly to query Solr's /suggest endpoint.

Add the View

In your app's views.py:

import json
import pysolr
from django.http import JsonResponse
from django.conf import settings

def search_suggestions(request):
    query = request.GET.get('q', '').strip()
    if not query:
        return JsonResponse({'suggestions': []})
    
    # Initialize connection to Solr using your Haystack config
    solr_client = pysolr.Solr(
        settings.HAYSTACK_CONNECTIONS['default']['URL'],
        timeout=10
    )
    
    # Fetch suggestions from Solr
    solr_response = solr_client.search(
        '',
        spellcheck_q=query,
        qt='/suggest'
    )
    
    # Parse suggestions from the raw Solr response
    suggestions = []
    spellcheck_data = solr_response.raw_response.get('spellcheck', {})
    if 'suggestions' in spellcheck_data:
        for item in spellcheck_data['suggestions']:
            if isinstance(item, dict) and 'suggestion' in item:
                suggestions.extend(item['suggestion'])
    
    # Remove duplicates and limit to 10 results
    unique_suggestions = list(set(suggestions))[:10]
    return JsonResponse({'suggestions': unique_suggestions})

Add a URL Route

Update your app's urls.py to map the view to a URL:

from django.conf.urls import url
from . import views

urlpatterns = [
    # ... your existing URLs
    url(r'^search-suggestions/$', views.search_suggestions, name='search_suggestions'),
]
Step 4: Add Frontend Autocomplete

Finally, add a search input and JavaScript to fetch and display suggestions as the user types.

Template Code

Add this to your search template:

<div class="search-container">
  <input type="text" id="search-input" placeholder="Search titles...">
  <ul id="suggestions-list"></ul>
</div>

<script>
const searchInput = document.getElementById('search-input');
const suggestionsList = document.getElementById('suggestions-list');

// Fetch suggestions on input
searchInput.addEventListener('input', function() {
    const query = this.value.trim();
    if (!query) {
        suggestionsList.innerHTML = '';
        return;
    }

    fetch(`{% url 'search_suggestions' %}?q=${encodeURIComponent(query)}`)
        .then(response => response.json())
        .then(data => {
            suggestionsList.innerHTML = '';
            data.suggestions.forEach(suggestion => {
                const li = document.createElement('li');
                li.textContent = suggestion;
                // Fill input when suggestion is clicked
                li.addEventListener('click', () => {
                    searchInput.value = suggestion;
                    suggestionsList.innerHTML = '';
                    // Optional: Submit your search form here
                });
                suggestionsList.appendChild(li);
            });
        })
        .catch(err => console.error('Failed to load suggestions:', err));
});

// Hide suggestions when clicking outside
document.addEventListener('click', (e) => {
    if (!searchInput.contains(e.target) && !suggestionsList.contains(e.target)) {
        suggestionsList.innerHTML = '';
    }
});
</script>
Quick Notes
  • Performance: If you have a huge dataset, buildOnCommit in Solr might slow down writes. You can switch to manually building the suggestion dictionary by calling http://localhost:8983/solr/your_core/suggest?spellcheck.build=true.
  • Filtering: Adjust the index_queryset in your Haystack index to include/exclude entries as needed.
  • Styling: Add CSS to the suggestions list to make it look like a proper autocomplete dropdown.

内容的提问来源于stack exchange,提问作者Dhaval Savalia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:27:59