Django haystack+solr搜索引擎部署的坑.


跟着<<Django by Example>> 一路做下來,到了搭建搜索引擎的步驟

默認的思路是用 

obj.objects.filter(body__icontains='framework')

然后把得到的QuerySet 返回到模板中使用

首先要確保你的java版本在 1.7或之上

使用 java -version 查看

 

http://archive.apache.org/dist/lucene/solr/ 然后到這個網站里下載 Solr 這里我使用的是4.10.4(不同版本之間的差異有點不一樣,慎重選擇.不然會被坑死)

然后進入example文件夾

java -jar start.jar //服務運行Solr;

  

 

打開你的瀏覽器,進入URL:http://127.0.0.1:8983/solr/  你會看到類似這種界面

 

 

我們要為我們的應用創建一個core ,首先要創建目錄樹

 

blog$ tree
.
├── conf
│   ├── core.properties
│   ├── lang
│   │   └── stopwords_en.txt
│   ├── protwords.txt
│   ├── _rest_managed.json
│   ├── schema.xml
│   ├── solrconfig.xml
│   ├── stopwords.txt
│   └── synonyms.txt
└── data
└── index
├── segments_1
├── segments.gen


 
        

  

solrconfig.xml文件中添加如下XML代碼:

?xml version="1.0" encoding="utf-8" ?>
<config>
    <luceneMatchVersion>LUCENE_36</luceneMatchVersion>
    <requestHandler name="/select" class="solr.StandardRequestHandler" default="true" />
    <requestHandler name="/update" class="solr.UpdateRequestHandler" />
    <requestHandler name="/admin" class="solr.admin.AdminHandlers" />
    <requestHandler name="/admin/ping" class="solr.PingRequestHandler">
        <lst name="invariants">
            <str name="qt">search</str>
            <str name="q">*:*</str>
        </lst>
    </requestHandler>
</config>


這是一個最小的Solr配置。編輯schema.xml文件,加入如下XML代碼:

<?xml version="1.0" ?> <schema name="default" version="1.5"> </schema>

  

然后我們創建一個自己的架構

 

 

  • name: blog
  • instanceDir: blog
  • dataDir: data
  • config: solrconfig.xml
  • schema: schema.xml

name字段是你想給這個core起的名字。instanceDir字段是你的core的目錄。dataDir是索引數據將要存放的目錄,它位於instanceDir目錄下面。config字段是你的Solr XML配置文件名。schema字段是你的Solr XML 數據架構(schema)文件名。

 

 

為了在Django中使用Solr,我們還需要Haystack。使用下面的命令,通過pip渠道安裝Haystack:


這里我們直接安裝最新版的,書上有指定版本.跟着做坑了我一個早上,幸好各種google下來解決了問題,在此記錄下,希望后面踩到坑的人也能順利渡劫. 不過最好下之前看看自己的django版本haystack支持不支持... 附上github項目地址 https://github.com/django-haystack/django-haystack/issues

pip isntall django-haystack

//Haystack能和一些搜索引擎后台交互。要使用Solr后端,你還需要安裝pysolr模塊。運行如下命令安裝它:


pip install pysolr

然后在setting 中添加它
INSTALLED_APPS = (
    # ...
    haystack', 
)

再添加搜索引擎后端
HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.solr_backend.SolrEngine',
        'URL': 'http://127.0.0.1:8983/solr/blog'
    },
}

  

在,我們必須將我們想要存儲在搜索引擎中的模型進行注冊。Haystack的慣例是在你的應用中創建一個search_indexes.py文件,然后在該文件中注冊你的模型(models)。在你的blog應用目錄下創建一個新的文件命名為search_indexes.py,添加如下代碼:

 

from haystack import indexes
from .models import Post

class PostIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    publish = indexes.DateTimeField(model_attr='publish')

    def get_model(self):
        return Post

    def index_queryset(self, using=None):
        return self.get_model().published.all()

  

這是一個Post模型(model)的自定義SearchIndex。通過這個索引(index),我們告訴Haystack這個模型(model)中的哪些數據必須被搜索引擎編入索引。這個索引(index)是通過繼承indexes.SearchIndexindexes.Indexable構建的。每一個SearchIndex都需要它的其中一個字段擁有document=True。按照慣例,這個字段命名為text。這個字段是一個主要的搜索字段。通過使用use_template=True,我們告訴Haystack這個字段將會被渲染成一個數據模板(template)來構建document,它會被搜索引擎編入索引(index)。publish字段是一個日期字段也會被編入索引。我們通過model_attr參數來表明這個字段對應Post模型(model)的publish字段。這個字段將用 被索引的Post對象的publish字段的內容 索引。

額外的字段,像這個為搜索提供額外的過濾器(filters),是非常有用的。get_model()方法必須返回將儲存在這個索引中的documents的模型(model)。index_queryset()方法返回將會被編入索引的對象的查詢集(QuerySet)。請注意,我們只包含了發布狀態的帖子。

 

現在,在blog應用的模板(templates)目錄下創建目錄和文件search/indexes/blog/post_text.txt,然后添加如下代碼:

{{ object.title }}
{{ object.tags.all|join:", " }}
{{ object.body }}

  

現在,我們已經有了一個自定義的搜索索引(index),我們需要創建合適的Solr架構(schema)。Solr的配置基於XML,所以我們必須為我們即將索引(index)的數據生成一個XML架構(schema)。非常幸運,haystack提供了一個基於我們的搜索索引(indexes),動態生成架構(schema)的方法。打開終端,運行以下命令:

python manage.py build_solr_schema

如果你看到的是這樣的,那么恭喜你配置成功...

如果不是這樣的,請去官網看看支持的版本和看看自己的版本對應不對應了...

在你的瀏覽器中打開 http://127.0.0.1:8983/solr/ 然后點擊Core Admin菜單欄,再點擊blog core,然后再點擊Reload按鈕:

索引數據(Indexing data)

讓我們blog中的帖子編輯索引(index)到Solr中。打開終端,執行以下命令:

python manage.py rebuild_index

y下一步

在瀏覽器中打開 http://127.0.0.1:8983/solr/#/blog 。在*Statistics下方,你會看到被編入索引(indexed)documents的數量,如下所示:

 

 

現在,在瀏覽器中打開 http://127.0.0.1:8983/solr/#/blog/query 。這是一個Solr提供的查詢接口。點擊Execute query按鈕。默認的查詢會請求你的core中所有被編入索引(indexde)的documents。你會看到一串帶有這個查詢結果的JSON輸出。輸出的documents如下所示:

{
    "id": "blog.post.1", "text": "Who was Django Reinhardt?\njazz, music\nThe Django web framework was named after the amazing jazz guitarist Django Reinhardt.", "django_id": "1", "publish": "2015-09-20T12:49:52Z", "django_ct": "blog.post" },

 

這是每個帖子在搜索索引(index)中存儲的數據。text字段包含了標題,通過逗號分隔的標簽(tags),還有帖子的內容,這個字段是在我們之前定義的模板(template)上構建的。

你已經使用過python manage.py rebuild_index來刪除索引(index)中的所有信息然后再次對documents進行索引(index)。為了不刪除所有對象而更新你的索引(index),你可以使用python manage.py update_index。另外,你可以使用參數--age=<num_hours>來更新少量的對象。為了保證你的Solr索引更新,你可以為這個操作設置一個定時任務(Cron job)

 

創建一個搜索視圖(view)

現在,我們要開始創建一個自定義視圖(view)來允許我們的用戶搜索帖子。首先,我們需要一個搜索表單(form)。編輯blog應用下的forms.py文件,加入以下表單:

class SearchForm(forms.Form):
    query = forms.CharField()

  我們會使用query字段來讓用戶引入搜索條件(terms)。編輯blog應用下的views.py文件,加入以下代碼:

def post_search(request):
    form = SearchForm()
    if 'query' in request.GET:
        form = SearchForm(request.GET)
        if form.is_valid():
            cd = form.cleaned_data
            results = SearchQuerySet().models(Post).filter(content=cd['query']).load_all()
            # return HttpResponse(results.count())
            # count total results
            total_results = results.count()


            return render(request,'blog/post/search.html',
                          {'form':form,
                          'cd':cd,
                          'results':results,
                           'total_results':total_results})

    return render(request,'blog/post/search.html',{'form':form})

  

搜索視圖(view)已經准備好了。我們還需要創建一個模板(template)來展示表單(form)和用戶執行搜索后返回的結果。在templates/blog/post/目錄下創建一個新的文件命名為search.html,添加如下代碼:

{% extends "blog/base.html" %}
{% block title %}Search{% endblock %}
{% block content %}
    {% if "query" in request.GET %}
        <h1>Posts containing "{{ cd.query }}"</h1>
        <h3>Found {{ total_results }} result{{ total_results|pluralize }}</h3>
        {% for result in results %}
            {% with post=result.object %}
                <h4><a href="{{ post.get_absolute_url }}">{{ post.title }}</a></h4>           
                {{ post.body|truncatewords:5 }}
            {% endwith %}
            {% empty %}
                   <p>There are no results for your query.</p>
        {% endfor %}    
        <p><a href="{% url "blog:post_search" %}">Search again</a></p>
    {% else %}
        <h1>Search for posts</h1>
        <form action="." method="get">
            {{ form.as_p }}
            <input type="submit" value="Search">
        </form>
    {% endif %}
{% endblock %}

 

添加視圖

url(r'^search/$', views.post_search, name='post_search'),

 

現在,在瀏覽器中打開 http://127.0.0.1:8000/blog/search/。你會看到如下圖所示的搜索表單(form):


 
 
輸入搜索就是這種效果了

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM