Haystack 설치 및 실행하기
Getting Started with Haystack
실습용으로 아래와 같이 간단한 노트 앱에 검색 기능을 붙여보자.
myapp/models.py
1 2 3 4 5 6 7 8 9 10 11 | from django.contrib.auth.models import User from django.db import models class Note(models.Model): userid = models.ForeignKey(User, related_name='user_note') pub_date = models.DateTimeField() title = models.CharField(max_length=200) body = models.TextField() def __unicode__(self): return self.title | cs |
1 2 3 4 5 6 7 8 9 10 | # python manage.py makemigrations Migrations for 'vikander': 0007_note.py: - Create model Note # python manage.py migrate Operations to perform: Apply all migrations: auth, sessions, admin, avatar, contenttypes, vikander Running migrations: Rendering model states... DONE Applying vikander.0007_note... OK | cs |
Installation
1 | # pip install django-haystack | cs |
Configuration
설정파일(settings.py) 내 INSTALLED_APPS 에 haystack 을 추가한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'haystack', 'vikander', 'avatar', 'django.contrib.humanize', ] | cs |
사용하는 백엔드의 종류가 알맞게 HAYSTACK_CONNECTION 추가한다. 본 포스팅에서는 엘라스틱서치의 경우이며, 다른 에제는 http://django-haystack.readthedocs.io/en/v2.5.1/tutorial.html#modify-your-settings-py 를 참조한다.
백엔드가 설치되어 있지 않는 경우에는 다음 링크를 참고하여 설치한다.
http://django-haystack.readthedocs.io/en/v2.5.1/installing_search_engines.html
1 2 3 4 5 6 7 | HAYSTACK_CONNECTIONS = { 'default': { 'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine', 'URL': 'http://127.0.0.1:9200/', 'INDEX_NAME': 'haystack', }, } | cs |
Handling data
서로 다른 모델 간에 하나의 SearchIndex 를 사용할 수도 있고, 인덱싱하고자하는 각각의 모델 타입별로 SearchIndex 를 만들 수도 있다.
SearchIndex 를 생성하기 위해서는 데이터를 저장하고자하는 필드와 get_model method 를 정의하기 위해 indexes.SearchIndex 와 indexes.Indexable 로 나누는 것이다.
앞서 만든 Note 모델에 대응하는 NoteIndex 를 아래와 같이 생성한다. 일반적으로 search_indexes.py 파일로 만들지만 꼭 그래야하는 것은 아니다.
search_indexes.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import datetime from haystack import indexes from .models import Note, User class NoteIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, use_template=True) title = indexes.CharField(model_attr='title') body = indexes.CharField(model_attr='body') author = indexes.CharField(model_attr='userid') pub_date = indexes.DateTimeField(model_attr='pub_date') def get_model(self): return Note def index_queryset(self, using=None): """Used when the entire index for model is updated.""" return self.get_model().objects.filter(pub_date__lte=datetime.datetime.now()) | cs |
모든 SearchIndex 는 document=True 라는 하나의 필드를 필요로 한다. 이는 haystack 와 검색엔진으로 하여금 어느 필드가 primary 인지를 알려준다.
추가적으로 텍스트 필드에 use_template=True 값을 제공하는데, 이는 검색엔진이 인덱싱하는 문서를 생성하는 데이터 템플릿을 사용하도록 해준다. templates/search/indexes/<myapp>/note_text.txt 라는 템플릿 디렉토리 내에 새로운 템플릿을 생성할 필요가 있다. 디렉토리의 위치 및 들어갈 코드는 아래와 같다.
1 2 3 4 5 6 7 | ├── templates │ ├── search │ │ └── indexes │ │ └── vikander │ │ └── note_text.txt |
1 2 3 | {{ object.title }} {{ object.userid.get_full_name }} {{ object.body }} | cs |
Setting Up The Views
URLconf 에 아래와 같이 뷰를 추가한다.
settings.py
1 2 3 4 5 | urlpatterns = [ url(r'^search/', include('haystack.urls')), ] | cs |
검색 템플릿을 만든다.
search/search.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <form method="get" action="."> <table> {{ form.as_table }} <tr> <td> </td> <td> <input type="submit" value="Search"> </td> </tr> </table> {% if query %} <h3>Results</h3> {% for result in page.object_list %} <p> <a href="{{ result.object.get_absolute_url }}">{{ result.object.title }}</a> </p> {% empty %} <p>No results found.</p> {% endfor %} {% if page.has_previous or page.has_next %} <div> {% if page.has_previous %}<a href="?q={{ query }}&page={{ page.previous_page_number }}">{% endif %}« Previous{% if page.has_previous %}</a>{% endif %} | {% if page.has_next %}<a href="?q={{ query }}&page={{ page.next_page_number }}">{% endif %}Next »{% if page.has_next %}</a>{% endif %} </div> {% endif %} {% else %} {# Show some example queries to run, maybe query syntax, something else? #} {% endif %} </form> | cs |
Reindex
이제 남은 것은 데이터베이스의 데이터를 검색 인덱스로 집어넣는 단계이다. 아래와 같은 에러가 발생하는 경우가 있다.
1 2 3 | # python manage.py rebuild_index raise MissingDependency("The 'elasticsearch' backend requires the installation of 'elasticsearch'. Please refer to the documentation.") haystack.exceptions.MissingDependency: The 'elasticsearch' backend requires the installation of 'elasticsearch'. Please refer to the documentation. | cs |
이와 관련하여 아래 링크가 도움이 된다.
Error: The 'elasticsearch' backend requires the installation of 'requests'. How do I fix it?
Can't get Elasticsearch working with Django
http://stackoverflow.com/questions/28257502/cant-get-elasticsearch-working-with-django
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # pip install pyelasticsearch Collecting pyelasticsearch Downloading pyelasticsearch-1.4.tar.gz (53kB) 100% |████████████████████████████████| 61kB 769kB/s Collecting certifi (from pyelasticsearch) Using cached certifi-2016.9.26-py2.py3-none-any.whl Collecting elasticsearch<2.0.0,>=1.3.0 (from pyelasticsearch) Downloading elasticsearch-1.9.0-py2.py3-none-any.whl (59kB) 100% |████████████████████████████████| 61kB 4.5MB/s Collecting urllib3<2.0,>=1.8 (from pyelasticsearch) Downloading urllib3-1.19.1-py2.py3-none-any.whl (104kB) 100% |████████████████████████████████| 112kB 4.7MB/s Collecting simplejson>=3.0 (from pyelasticsearch) Downloading simplejson-3.10.0.tar.gz (77kB) 100% |████████████████████████████████| 81kB 3.0MB/s Requirement already satisfied: six<2.0,>=1.4.0 in /root/anaconda/envs/envalicia/lib/python3.5/site-packages (from pyelasticsearch) Building wheels for collected packages: pyelasticsearch, simplejson Running setup.py bdist_wheel for pyelasticsearch ... done Stored in directory: /root/.cache/pip/wheels/1b/0c/0e/65b564e99a54d8db71e27f3997e55a27a2ab74960f001dac01 Running setup.py bdist_wheel for simplejson ... done Stored in directory: /root/.cache/pip/wheels/43/c5/ef/edcebbb19becffd2ba75bf219afdbb4ca85198b2d909f1b31b Successfully built pyelasticsearch simplejson Installing collected packages: certifi, urllib3, elasticsearch, simplejson, pyelasticsearch Successfully installed certifi-2016.9.26 elasticsearch-1.9.0 pyelasticsearch-1.4 simplejson-3.10.0 urllib3-1.19.1 | cs |
1 2 3 4 5 6 7 8 | # python manage.py rebuild_index WARNING: This will irreparably remove EVERYTHING from your search index in connection 'default'. Your choices after this are to restore from backups or rebuild via the `rebuild_index` command. Are you sure you wish to continue? [y/N] y Removing all documents from your index because you said so. All documents removed. Indexing 0 notes | cs |
정상적으로 리인덱스를 마쳤다.
실제 화면은 다음과 같다.
http://django-haystack.readthedocs.io/en/v2.5.0/tutorial.html#installation
'프로그래밍 Programming' 카테고리의 다른 글
django 자동완성 구현하기 django-autocomplete-light (0) | 2016.12.26 |
---|---|
장고 내장 필터(소수점 표시) Built-in filter reference (0) | 2016.12.17 |
우분투에 엘라스틱서치 설치하기 How To Install and Configure Elasticsearch on Ubuntu 14.04 (0) | 2016.12.06 |
비지도 학습 (2) - k평균으로 손글씨 숫자 군집화 (0) | 2016.12.03 |
비지도 학습 (1) - 주성분 분석(Principal Component Analysis, PCA) (0) | 2016.12.02 |