Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

(시리즈 글이 5개 있습니다.)
개발 환경 구성: 392. 윈도우 환경에서 curl.exe를 이용한 elasticsearch 6.x 기본 사용법
; https://www.sysnet.pe.kr/2/0/11663

개발 환경 구성: 393. 윈도우 환경에서 elasticsearch의 한글 형태소 분석기 설치
; https://www.sysnet.pe.kr/2/0/11664

개발 환경 구성: 394. 윈도우 환경에서 elasticsearch의 한글 블로그 검색 인덱스 구성
; https://www.sysnet.pe.kr/2/0/11669

.NET Framework: 791. C# - ElasticSearch를 위한 Client 라이브러리 제작
; https://www.sysnet.pe.kr/2/0/11676

개발 환경 구성: 507. Elasticsearch 6.6부터 기본 추가된 한글 형태소 분석기 노리(nori) 사용법
; https://www.sysnet.pe.kr/2/0/12309




윈도우 환경에서 elasticsearch의 한글 블로그 검색 인덱스 구성

지난 글에서 elasticsearch의 간단한 사용법을 알아봤는데요,

윈도우 환경에서 curl.exe를 이용한 elasticsearch 6.x 기본 사용법
; https://www.sysnet.pe.kr/2/0/11663

이번에는 그것을 이용해 블로그 글을 검색하는 환경을 구성해 보겠습니다. 우선, 이전 글에 따라 한글 검색을 도와주는 플러그인은 설치해야 합니다.

윈도우 환경에서 elasticsearch의 한글 형태소 분석기 설치
; https://www.sysnet.pe.kr/2/0/11664

그 외에 블로그의 특성상 html 태그가 들어갈 것이므로 "openkoreantext-analyzer"를 기본으로 사용할 수는 없고, 다음과 같이 "html_strip" 필터를 추가로 구성해 analyzer를 만들어야 합니다.

{
    "settings": {
        "analysis": {
            "analyzer": {
                "blogtext_analyzer": {
                    "type": "custom",
                    "tokenizer": "openkoreantext-tokenizer",
                    "char_filter": [
                        "html_strip",
                        "openkoreantext-normalizer"
                    ],
                    "filter": [
                        "openkoreantext-stemmer",
                        "openkoreantext-redundant-filter"
                    ]
                }
            }
        }
    }
}

편의상 위의 내용을 settings.json 파일로 저장하고 다음과 같이 명령을 내리면 인덱스가 생성됩니다.

curl -XDELETE "http://localhost:9200/my_blog/"

curl -XPUT "http://localhost:9200/my_blog/" -H "Content-Type: application/json" -d "@settings.json"

또는 불편을 감수하고 다음과 같이 명령을 내리면 됩니다.

curl -XPUT "http://localhost:9200/my_blog/" -H "Content-Type: application/json" -d "{ \"settings\": { \"analysis\": { \"analyzer\": { \"blogtext_analyzer\": { \"type\": \"custom\", \"tokenizer\": \"openkoreantext-tokenizer\", \"char_filter\": [ \"html_strip\", \"openkoreantext-normalizer\" ], \"filter\": [ \"lowercase\", \"openkoreantext-stemmer\", \"openkoreantext-redundant-filter\" ] } } } } }"

사용자 정의 구성으로 blogtext_analyzer를 생성했으니, 이제 Type 정의에서 다음과 같이 적용할 수 있습니다.

{
    "articles": {
        "properties": {
            "writer": {
                "type": "text",
                "index": "false"
            },
            "wid": { "type": "integer" },
            "contents": {
                "type": "text",
                "analyzer": "blogtext_analyzer"
            },
            "registered": { "type": "date" }
        }
    }
}

위의 내용을 "articles.json" 파일로 저장하고 다음과 같이 명령을 내리거나,

curl -XPUT "http://localhost:9200/my_blog/articles/_mapping" -H "Content-Type: application/json" -d "@articles.json"

인라인으로 -d 옵션을 이용해 모두 써줘도 됩니다.

curl -XPUT "http://localhost:9200/my_blog/articles/_mapping" -H "Content-Type: application/json" -d "{ \"articles\" : { \"properties\" : {  \"writer\" : {\"type\" : \"text\", \"index\" : \"false\"}, \"wid\" : {\"type\" : \"integer\"}, \"contents\" : {\"type\" : \"text\", \"analyzer\": \"blogtext_analyzer\" }, \"registered\" : {\"type\" : \"date\"} } } }"

정상적으로 타입이 생성되었는지 Type 정의를 확인하고,

curl -XGET "http://localhost:9200/my_blog/articles/_mapping?pretty"

데이터 몇 개를 넣은 다음,

curl -XPUT "http://localhost:9200/my_blog/articles/1" -H "Content-Type: application/json" -d 
"{ 
    "name" : "tester", 
    "wid": 16, 
    "contents": "^gacutil.exe^를 실행해 ^<a href='dotnet'^>닷넷^</a^> DLL을 GAC에 등록하려 할 때 다음과 같은 식의 오류가 발생한다면?", 
    "registered":"2017-04-29T10:16:00" 
}"

curl -XPUT "http://localhost:9200/my_blog/articles/2" -H "Content-Type: application/json" -d 
"{ 
    "name" : "tester", 
    "wid": 17, 
    "contents": "한국어를 처리하는 예시입니닼ㅋㅋ", 
    "registered":"2017-04-29T10:16:00" 
}"

curl -XPUT "http://localhost:9200/my_blog/articles/3" -H "Content-Type: application/json" -d
"{ 
    "name" : "tester", 
    "wid": 17, 
    "contents": "테스트 이미지^<img alt=\\"test\\" ^>입니다.", 
    "registered":"2017-04-29T10:16:00" 
}"

curl -XPUT "http://localhost:9200/my_blog/articles/1" -H "Content-Type: application/json" -d "{ \"name\" : \"tester\", \"wid\": 16, \"contents\": \"^<b^>gacutil.exe^</b^>를 실행해 ^<a href='dotnet'^>닷넷^</a^> DLL을 GAC에 등록하려 할 때 다음과 같은 식의 오류가 발생한다면?\", \"registered\":\"2017-04-29T10:16:00\" }"

curl -XPUT "http://localhost:9200/my_blog/articles/2" -H "Content-Type: application/json" -d "{ \"name\" : \"tester\", \"wid\": 17, \"contents\": \"한국어를 처리하는 예시입니닼ㅋㅋ\", \"registered\":\"2017-04-29T10:16:00\" }"

curl -XPUT "http://localhost:9200/my_blog/articles/3" -H "Content-Type: application/json" -d "{ \"name\" : \"tester\", \"wid\": 18, \"contents\": \"테스트 이미지^<img alt=\\\"test\\\" ^>입니다.\", \"registered\":\"2017-04-29T10:16:00\" }"

검색 쿼리를 날려볼 수 있습니다.

curl -XGET "http://localhost:9200/my_blog/articles/_search" -H "Content-Type: application/json" -d "{ \"query\": { \"match\": { \"contents\": \"gacutil\" } } }"

{"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":1,"max_score":0.2876821,"hits":[{"_index":"my_blog","_type":"articles","_id":"1","_score":0.2876821,"_source":{ "name" : "tester", "wid": 16, "contents": "<b>gacutil.exe</b>를 실행해 <a href='dotnet'>닷넷</a> DLL을 GAC에 등록하려 할 때 다음과 같은 식의 오 류가 발생한다면?", "registered":"2017-04-29T10:16:00" }}]}}

html_strip 필터를 적용했기 때문에 html 태그 내에 있던 내용은 검색되지 않습니다.

curl -XGET "http://localhost:9200/my_blog/articles/_search" -H "Content-Type: application/json" -d "{ \"query\": { \"match\": { \"contents\": \"href\" } } }"

{"took":0,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}

html_strip이 좋긴 한데, 아쉽게도 img의 alt 태그와 같은 내용에 대한 배려가 없군요. ^^

curl -XGET "http://localhost:9200/my_blog/articles/_search" -H "Content-Type: application/json" -d "{ \"query\": { \"match\": { \"contents\": \"test\" } } }"

{"took":0,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}




curl.exe에서 HTML에 대한 인코딩이 잘못되면 다음과 같이 황당한 오류가 발생합니다.

c:\temp> curl -XPUT "http://localhost:9200/my_blog/articles/5" -H "Content-Type: application/json" -d "{ \"name\" : \"tester\", \"wid\": 17, \"address\": \"한국어를 <b>처리</b> 예시\", \"registered\":\"2017-04-29T10:16:00\" }"

The system cannot find the file specified.

왜냐하면, Windows Shell 명령어에서 <, > 문자는 Redirection 용도로 사용하기 때문입니다. 따라서 <, >와 같은 문자는 '^' 문자를 이용해 escape 처리를 해야 합니다.




참고로 openkoreantext-analyzer의 기본 설정은 "open-korean-text/elasticsearch-analysis-openkoreantext" 문서에 의하면 다음과 같다고 합니다.

"openkoreantext-analyzer": {
    "type": "custom",
    "tokenizer": "openkoreantext-tokenizer",
    "char_filter": [
        "openkoreantext-normalizer"
    ],
    "filter": [
        "openkoreantext-stemmer",
        "openkoreantext-redundant-filter",
        "classic",
        "length",
        "lowercase"
    ]
}

위의 구성에서 filter 부분의 순서가 의미가 있는데, 만약 lowercase를 다음과 같이 위로 설정해 놓으면,

"filter": [
    "lowercase"
    "openkoreantext-stemmer",
    "openkoreantext-redundant-filter",
]

다음과 같은 오류가 발생합니다.

{"error":{"root_cause":[{"type":"class_cast_exception","reason":"org.apache.lucene.analysis.LowerCaseFilter cannot be cast to org.apache.lucene.analysis.ko.KoreanTokenPrepareable"}],"type":"class_cast_exception","reason":"org.apache.lucene.analysis.LowerCaseFilter cannot be cast to org.apache.lucene.analysis.ko.KoreanTokenPrepareable"},"status":500}


만약 위와 같은 오류가 발생한다면 filter 항목의 순서를 조정할 필요가 있는 것입니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 8/24/2018]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 31  32  33  34  35  36  37  38  [39]  40  41  42  43  44  45  ...
NoWriterDateCnt.TitleFile(s)
12655정성태6/1/20217713오류 유형: 722. windbg/sos - savemodule - Fail to read memory
12654정성태5/31/20217734오류 유형: 721. Hyper-V - Saved 상태의 VM을 시작 시 오류 발생
12653정성태5/31/202110403.NET Framework: 1060. 닷넷 GC에 새롭게 구현되는 DPAD(Dynamic Promotion And Demotion for GC)
12652정성태5/31/20218502VS.NET IDE: 164. Visual Studio - Web Deploy로 Publish 시 암호창이 매번 뜨는 문제
12651정성태5/31/20218717오류 유형: 720. PostgreSQL - ERROR: 22P02: malformed array literal: "..."
12650정성태5/17/20218037기타: 82. OpenTabletDriver의 버튼에 더블 클릭을 매핑 및 게임에서의 지원 방법
12649정성태5/16/20219390.NET Framework: 1059. 세대 별 GC(Garbage Collection) 방식에서 Card table의 사용 의미 [1]
12648정성태5/16/20218012사물인터넷: 66. PC -> FTDI -> NodeMCU v1 ESP8266 기기를 UART 핀을 연결해 직렬 통신하는 방법파일 다운로드1
12647정성태5/15/20219285.NET Framework: 1058. C# - C++과의 연동을 위한 구조체의 fixed 배열 필드 사용파일 다운로드1
12646정성태5/15/20218378사물인터넷: 65. C# - Arduino IDE의 Serial Monitor 기능 구현파일 다운로드1
12645정성태5/14/20218093사물인터넷: 64. NodeMCU v1 ESP8266 - LittleFS를 이용한 와이파이 접속 정보 업데이트파일 다운로드1
12644정성태5/14/20219228오류 유형: 719. 윈도우 - 제어판의 "프로그램 및 기능" / "Windows 기능 켜기/끄기" 오류 0x800736B3
12643정성태5/14/20218424오류 유형: 718. 서버 유형의 COM+ 사용 시 0x80080005(Server execution failed) 오류 발생
12642정성태5/14/20219357오류 유형: 717. The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.
12641정성태5/13/20219050디버깅 기술: 179. 윈도우용 .NET Core 3 이상에서 Windbg의 sos 사용법
12640정성태5/13/202112012오류 유형: 716. RDP 연결 - Because of a protocol error (code: 0x112f), the remote session will be disconnected. [1]
12639정성태5/12/20218873오류 유형: 715. Arduino: Open Serial Monitor - The module '...\detection.node' was compiled against a different Node.js version using NODE_MODULE_VERSION
12638정성태5/12/20219802사물인터넷: 63. NodeMCU v1 ESP8266 - 펌웨어 내 파일 시스템(SPIFFS, LittleFS) 및 EEPROM 활용
12637정성태5/10/20219432사물인터넷: 62. NodeMCU v1 ESP8266 보드의 A0 핀에 다중 아날로그 센서 연결 [1]
12636정성태5/10/20219654사물인터넷: 61. NodeMCU v1 ESP8266 보드의 A0 핀 사용법 - FSR-402 아날로그 압력 센서 연동파일 다운로드1
12635정성태5/9/20218961기타: 81. OpenTabletDriver를 (관리자 권한으로 실행하지 않고도) 관리자 권한의 프로그램에서 동작하게 만드는 방법
12634정성태5/9/20218012개발 환경 구성: 572. .NET에서의 신뢰도 등급 조정 - 외부 Manifest 파일을 두는 방법파일 다운로드1
12633정성태5/7/20219494개발 환경 구성: 571. UAC - 관리자 권한 없이 UIPI 제약을 없애는 방법
12632정성태5/7/20219678기타: 80. (WACOM도 지원하는) Tablet 공통 디바이스 드라이버 - OpenTabletDriver
12631정성태5/5/20219593사물인터넷: 60. ThingSpeak 사물인터넷 플랫폼에 ESP8266 NodeMCU v1 + 조도 센서 장비 연동파일 다운로드1
12630정성태5/5/20219913사물인터넷: 59. NodeMCU v1 ESP8266 보드의 A0 핀 사용법 - CdS Cell(GL3526) 조도 센서 연동파일 다운로드1
... 31  32  33  34  35  36  37  38  [39]  40  41  42  43  44  45  ...