본문 바로가기

Dev/web

python, django,haystack, elasticsearch 장고 엘라스틱서치 연동 - 2(검색시 맞춤법, 자동완성)

튜토리얼이 두 파트로 나눠서 작성중인데, 첫번째 글은 어떻게 엘라스틱과 헤이스택을 설치하는지, search indexes 만들기, 질의날리기 를 했음

이번에는 자동완성 기능과 맞춤법 검사후 제안, 그리고 커스텀 백엔드 만드는걸 해보겠음


Spelling Suggestions


아마 한글은 안될것같지만 이거 일단 실습해보고 나중에 은전한닢을 등록하든가 해야될듯

SearchIndex에 text필드를 미러링하는 특별한 필드하나를 만들어주자

import datetime
from haystack import indexes
from .models import Post


class PostIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
author = indexes.CharField(model_attr='user')
pub_date = indexes.DateTimeField(model_attr='pub_date')
suggestions = indexes.FacetCharField()

def prepare(self, obj):
prepared_data = super(PostIndex, self).prepare(obj)
prepared_data['suggestions'] = prepared_data['text']
return prepared_data

def get_model(self):
return Post

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())

그리고 settings.py에 스펠체크 컴포넌트 추가해줌

HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack_elasticsearch5.Elasticsearch5SearchEngine',
'URL': 'http://127.0.0.1:9201/',
'INDEX_NAME': 'test_backend',
'INCLUDE_SPELLING': True,
}
}

그리고는 views.py 에다가

from django.shortcuts import render
from haystack.query import SearchQuerySet
from .models import Post

# Create your views here.
def post_list(request):
sqs = SearchQuerySet().all()
print(sqs.count())

results = SearchQuerySet().filter(content='hello')
for t in results:
print(t.author)
print(t.text)

suggestedSearchTerm = SearchQuerySet().spelling_suggestion("hwllo")
print(suggestedSearchTerm)

return render(request, 'blogg/post_list.html')

를 입력함

잘못된 hwllo를 입력했는데 콘솔창에 hello라 나옴 ㅎㄷㄷ


Autocomplete Functionality

역시 헤이스택이용하면 쉽게 구현할수 있음

아 근데 한글 안되면 무슨의미가 있냐 ㅡㅡ;



그럼;; 어캐하지? es에 은전한닢 적용시켜봐야겠음 

은전한닢 적용할려고 ex 5.5.0 으로 다운그레이드 시킴


은전한닢 다운 및 적용

http://www.kwangsiklee.com/ko/2017/07/%EC%9D%80%EC%A0%84%ED%95%9C%EB%8B%A2-%EC%84%A4%EC%B9%98-%EC%99%84%EC%A0%84%EC%A0%95%EB%B3%B55-5-0/

http://blog.indexall.net/2017/05/installed-elasticsearch-analysis-mecab.html


이거 보고 적용함

그리고 해보니 인덱스 만들때 한글분석기가 적용된 인덱스를 만듦(이미만들어진 거에는 적용안됨)

즉, data가 존재하는 상황에서는 analyzer를 추가로 설정하는 것을 허용하지 않음, 


분석기가 잘 설정됐는지 확인하려면

메핑구조 만들고

curl -XPUT '127.0.0.1:9200/korean/' -d '{
"settings" : {
    "index":{
      "analysis":{
        "analyzer":{
          "korean":{
            "type":"custom",
            "tokenizer":"mecab_ko_standard_tokenizer"
          }
        }
      }
    }
  },
  "mappings": {
    "text" : {
      "properties" : {
        "message" : {
          "type" : "string",
          "analyzer": "korean"
        }
      }
    }
  }
}'

값 넣고 (이때 미친 자꾸 값넣으면 엘라스틱서치 튕김 ㅡㅡ 다시 실행할땐 이렇게 실행하셈: export LD_LIBRARY_PATH=/usr/local/lib; ./elasticsearch) 아.. 리눅스  잘 하고 싶다아아

curl -XPUT '127.0.0.1:9200/korean/text/1?pretty' -d '

{ "message" : "시발아 쫌 돼라 진짜 미치겠네"}'


전문검색으로 조회

curl -XGET '127.0.0.1:9200/korean/_search?pretty' -d '
 {
 "query" : {
 "match" : {
 "message" : "시발"
 }
 }
 }
'

하면 아까는 "바보야" 해야지 검색되었던것이 이제는 "바보"만 입력해도 검색이 됨

이것이 은전한닢..



그럼 장고모델에서 만든 인덱스에다가 mapping구조로 한글분석기 추가하면 되는것?

하지만 이미 데이터가 들어가 있는 인덱스는 정적매핑구조가 안먹는데 ..


part3에서 계속..



메모: python3 manage.py rebuild_index