프로젝트/AWS winter camp - ELK&AWS 프로젝트

Elasticsearch, django - rest_framework로 검색엔진 만들기 - 3차 트러블슈팅(해결)

dayeonsheep 2024. 2. 3. 16:01

 

https://ksb-dev.tistory.com/309

 

엘라스틱서치 8.X 도커로 무작성 실행해보기

1. 개요 검색엔진으로 유명한 엘라스틱 서치(Elastic Search)를 도커로 실행해 볼 것입니다. 엘라스틱 서치 버전 8 부터 Security가 default로 설정되어 있기 때문에, 이전 버전과 달리 비밀번호를 설정해

ksb-dev.tistory.com

 

https://simpleisbetterthancomplex.com/tutorial/2018/12/19/how-to-use-jwt-authentication-with-django-rest-framework.html

 

How to Use JWT Authentication with Django REST Framework

JWT stand for JSON Web Token and it is an authentication strategy used by client/server applications where theclient is a Web application using JavaScript an...

simpleisbetterthancomplex.com

 

#settings.py

#...

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework_simplejwt.authentication.JWTAuthentication'
    ],
    'DEFAULT_PERMISSION_CLASSES': [],
}

#...

ELASTICSEARCH_DSL = {
    'default': {
        'hosts': 'elasticsearch:9200',
    },
}
# search_app/urls.py

from search_app import views  
from django.urls import path  
from rest_framework_simplejwt import views as jwt_views
  
urlpatterns = [  
    path('', views.SearchView.as_view()),  
    path('api/token/', jwt_views.TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', jwt_views.TokenRefreshView.as_view(), name='token_refresh')
]

 

 

https://github.com/sibtc/drf-jwt-example

 

GitHub - sibtc/drf-jwt-example: Code samples of the tutorial "How to Use JWT Authentication with Django REST Framework"

Code samples of the tutorial "How to Use JWT Authentication with Django REST Framework" - GitHub - sibtc/drf-jwt-example: Code samples of the tutorial "How to Use JWT Authentication ...

github.com

 

 

"detail": "Method \"GET\" not allowed."

 

 

https://stackoverflow.com/questions/57302570/detail-method-get-not-allowed-django-rest-framework

 

"detail": "Method \"GET\" not allowed." Django Rest Framework

I know this question maybe a duplicate, but I have tried many solutions and could not understand any. I have followed this tutorial exactly and yet I get this error on the 'userlist' page. Everything

stackoverflow.com

 

 

python3 manage.py runserver 하고

http://127.0.0.1:8000/

에 접속할 때 로그인하라는 창 뜨는건

createsuperuser 만들어서 접속하니 되었다.

 

그리고 http://127.0.0.1:8000/admin/ 에 접속하니 auth 관련한걸 확인할 수 있었다...

 

 

$python3 manage.py search_index --rebuild
/Users/yangdayeon/myvenv/lib/python3.11/site-packages/django_elasticsearch_dsl/management/commands/search_index.py:301: ElasticsearchWarning: this request accesses system indices: [.kibana_analytics_8.11.3_001, .apm-custom-link, .kibana_task_manager_8.11.3_001, .ml-inference-000005, .fleet-policies-7, .kibana_security_solution_8.11.3_001, .fleet-servers-7, .security-tokens-7, .transform-internal-007, .security-7, .async-search, .kibana_security_session_1, .kibana_alerting_cases_8.11.3_001, .security-profile-8, .fleet-enrollment-api-keys-7, .apm-agent-configuration, .kibana_ingest_8.11.3_001, .fleet-agents-7, .fleet-policies-leader-7, .ml-inference-native-000002, .kibana_8.11.3_001], but in a future major version, direct access to system indices will be prevented by default
  for index in self.es_conn.indices.get_alias().values():
Are you sure you want to delete the 'book_index' indices? [y/N]: y
Deleting index 'book_index'
Creating index 'book_index'

까지 되길래 되는줄알았는데

다시 오류 뜸

 

migrate를 다시 해줬더니 됨

 

settings.py 에 이거 추가해주고

ELASTICSEARCH_DSL = {
    'default': {
        'cloud_id': 'cloudid',
        'http_auth': ('id', 'password')
    },
}


/Users/yangdayeon/myvenv/lib/python3.11/site-packages/elasticsearch/_sync/client/__init__.py, line 196, in __init__

__init__.py에서 

 

def __init__ 부분 cloud_id 부분에 팀 cloud_id 추가해줬더니 

드디어   ...  ... auth 에러 안남... 
근데 이제 search param 에러 남

그래서 views.py에서 

# 검색어
        search_word = request.query_params.get('search','주식')


이렇게 기본 검색어 설정했는데 안됨

views.py에서 이 부분에 수정

    def get(self, request):
        es = Elasticsearch(
            [
                {
                    'host': 'localhost:9200',
                    'cloud_id': 'cloudid값',
                    'http_auth': ('elastic', 'password')
                }
            ]
        )


 이랬더니 다시 

ValueError at /

The 'cloud_id' and 'hosts' parameters are mutually exclusive

Request Method:Request URL:Django Version:Exception Type:Exception Value:Exception Location:Raised during:Python Executable:Python Version:Python Path:Server time:

GET
http://127.0.0.1:8000/
5.0.1
ValueError
 
/Users/yangdayeon/myvenv/lib/python3.11/site-packages/elasticsearch/_sync/client/utils.py, line 104, in client_node_configs
search_app.views.SearchView
/Users/yangdayeon/myvenv/bin/python3
3.11.1
 
Fri, 02 Feb 2024 20:11:41 +0000


이 에러가 뜨기 시작
utils.py에서 

def client_node_configs(
    hosts: Optional[_TYPE_HOSTS] = 'localhost:9200',
    cloud_id: Optional[str] = 'cloudid값',
    requests_session_auth: Optional[Any] = None,
    **kwargs: Any,
) -> List[NodeConfig]:
    if cloud_id is not None:
        if hosts is not None:
            raise ValueError(
                "The 'cloud_id' and 'hosts' parameters are mutually exclusive"
            )
        node_configs = cloud_id_to_node_configs(cloud_id)
    else:
        assert hosts is not None
        node_configs = hosts_to_node_configs(hosts)



이 부분 수정...했다가 이것저것 수정하다가 다시 원상복귀...

애초에 이 elasticsearch 다 까서 하는 게 아니라

django에서 es 하는걸로 연결이 되는거라 얘는 수정할 필요가 없는......

es = Elasticsearch(
  cloud_id=ELASTIC_CLOUD_ID,
  api_key=ELASTIC_API_KEY,
  request_timeout=600
)

 

 

그리고 API key 를 넣으려고

일단 API로 올리기

# search_app/views.py

from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator

from rest_framework.views import APIView  
from rest_framework.response import Response  
from rest_framework import status  

from rest_framework.authentication import BasicAuthentication, SessionAuthentication
from rest_framework.permissions import IsAuthenticated

from elasticsearch import Elasticsearch  

from .search_indexes import *  # Elasticsearch DSL이 정의된 인덱스 import

@method_decorator(csrf_exempt,name='dispatch')
class SearchView(APIView):
    authentication_classes = [BasicAuthentication, SessionAuthentication]
    permission_classes = [IsAuthenticated]

    def get(self, request):
        es = Elasticsearch(
            cloud_id= 'cloudid값',
            api_key='key값',
            request_timeout=600
        )

        # 검색어
        search_word = request.query_params.get('search', '주식') #기본 검색어를 주식으로 설정

        if not search_word:
            return Response(status=status.HTTP_400_BAD_REQUEST, data={'message': 'search word param is missing'})

        docs = es.search(index='book_all',
                         body={
                             "query": {
                                 "multi_match": {
                                     "query": search_word,
                                     "fields": ["title", "content"]
                                 }
                             }
                         })

        data_list = docs['hits']

        return Response(data_list)

 

 

스,껄. 
드디어 200 OK가 나오다.

근데 이제 fields 변수명? 필드명이 안맞아서 검색이 제대로 안돼서 다시 맞추기

 

        # 검색어
        search_word = request.query_params.get('search', '주식')

        if not search_word:
            return Response(status=status.HTTP_400_BAD_REQUEST, data={'message': 'search word param is missing'})

        docs = es.search(index='book_all',
                         body={
                             "query": {
                                 "multi_match": {
                                     "query": search_word,
                                     "fields": ["Title", "PublisherReview"] 
                                 }
                             }
                         })

저 필드값을 book_all에 올린 필드명으로 수정해줬더니

주식들어간게 다 나오다... 
감격 스러움, 감정이 북받침, 

 

그리고 이제 ngram 연결하고

우선 Title로만 테스트 한 다음에

되는거 확인 후 author / publisher/ indexcontent/publisherreview 에 단어 들어가는 것도 검색되게 하면 됨

 

포스트맨에서도 검색 잘 된다... 


이 뒤에 찾은 레퍼런스 중에 내가 만든 거랑 가장 비슷한 레퍼런스↓
https://velog.io/@sliverki/ELK-%EA%B2%80%EC%83%89-%EC%97%94%EC%A7%84-%EC%B5%9C%EC%A0%81%ED%99%94

 

[elasticSearch] django+elastic 연동하여 검색엔진 최적화 하기

docker환경에서 django와 elasticsearch를 연동하여 검색엔진 최적화 하는 방법과 절차에 대한 게시글 입니다.! elasticSearch에대한 개념들은 따로 정리해 두었습니다.

velog.io

 

하지만 현재의 문제!

일반 검색이라서 

n-gram 적용해서 '엔드'만 검색해도 '백엔드', '프론트엔드' 얘네가 나와야되는데

지금은 안나온다

 

그래서 그거 수정~~과정은 다음글에서 

 

오류 수정하면서 느끼는 나의 문제점
코드를 정확히 이해하고 하는 게 아니라 에러나는 부분만 조금씩 고치면서 돌아가는 것만 파악하다보니
내가 이미 짜놓은 코드에서 이 부분이 필요한 코드인지, 아니면 불필요한 코드인지 구분이 안된다.