學(xué)習(xí)日志 211230 elasticsearch同義詞 從java端發(fā)起調(diào)用
# 211230
## 繼續(xù)搞同義詞字典上傳
- 上傳文件給pod有以下幾種方式
? - 使用configMap
? ? - 可共享 有大小限制 最多3M
? - 使用pvc
? ? - 不可共享 擴(kuò)容的話需要手工對(duì)擴(kuò)出來(lái)的pod再上傳
? - 使用initContainers指令做curl
? ? - 不需要重復(fù)操作
? ? - 需要一個(gè)源
? - 提前做好docker image
? ? - 不需要重復(fù)操作
? ? - 比較麻煩
? - 綜上 我們嘗試一下initContainers
? ? - 源用內(nèi)部nginx
? ? - 內(nèi)部nginx上的文件 使用pvc cp的方式
- 搞一個(gè)內(nèi)部nginx
? - 參考 https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/
? - 不寫cpu和內(nèi)存 看一下默認(rèn)是多少
? ? - 全是0
? - port-forward 80 出錯(cuò)
? ? - 使用 `kubectl run -i --tty --image busybox:1.28 dns-test --restart=Never --rm /bin/sh`
? ? - 創(chuàng)建dns檢查環(huán)境
? ? - 使用 nslookup mycluster-nginx-0.mycluster-nginx
? ? - 發(fā)現(xiàn)DNS不通 懷疑service有問(wèn)題
? ? - 檢查service發(fā)現(xiàn) service的selector寫錯(cuò)了
? ? - 修復(fù)后重新apply -f
? ? - 重新port-forward
? ? - 檢查localhost:80 可以訪問(wèn)
? - 上傳文件
? ? - 采用 kubectl cp指令
? ? - `kubectl cp .\synonym\synonyms.json mycluster-nginx-0:/usr/share/nginx/html`
? ? - 其中 /usr/share/nginx/html 目錄是nginx讀取的源目錄
? ? - 也是pvc 掛載的目錄
? ? - 測(cè)試 http://localhost/synonyms.json
- 讓elasticsearch使用initContainers 將該文件copy到自己的運(yùn)行環(huán)境
? - 指令格式
? - 前面的 sh -c | 不變
? - 后面指令為
? - `mkdir /usr/share/elasticsearch/config/dictionaries && curl -o /usr/share/elasticsearch/config/dictionaries/synonyms.json http://mycluster-nginx-0.mycluster-nginx/synonyms.json`
? - 注意需要mkdir 不然dictionaries目錄不存在
- elasticsearch報(bào)格式不對(duì)
? - 修改同義詞詞典的格式
? - 不需要json格式
? ? ```
? ? s(100001740,1,'entity',n,1,11).
? ? s(100001930,1,'physical entity',n,1,0).
? ? s(100002137,1,'abstraction',n,6,0).
? ? ```
? - 重新上傳到nginx上
? - 修改es的k8s描述文件中initContainers的文件名
- 測(cè)試
```
PUT /test_index
{
? "settings": {
? ? "index": {
? ? ? "analysis": {
? ? ? ? "analyzer": {
? ? ? ? ? "synonym": {
? ? ? ? ? ? "tokenizer": "whitespace",
? ? ? ? ? ? "filter": [ "synonym" ]
? ? ? ? ? }
? ? ? ? },
? ? ? ? "filter": {
? ? ? ? ? "synonym": {
? ? ? ? ? ? "type": "synonym",
? ? ? ? ? ? "format": "wordnet",
? ? ? ? ? ? "synonyms_path": "dictionaries/synonyms.txt"
? ? ? ? ? }
? ? ? ? }
? ? ? }
? ? }
? }
}
POST /test_index/_analyze
{
? "analyzer": "synonym",
? "text":"person"
}
```
? - 結(jié)果 person 在wordnet中有6個(gè)同義詞
## 應(yīng)用分析器到索引
- 我們自己的`test_doc`原始字段只有`id``doc`
- 為doc字段建一個(gè)subfield叫做`doc.synonym`
- 先建對(duì)應(yīng)的自定義analyzer
? - tokenizer standard
? - filter
? ? - lowercase
? ? - asciifolding
? ? - snowball
? ? - synonym
- 構(gòu)建期采用synonym的filter, 搜索時(shí)則采用synonym_graph
- 由于不能針對(duì)已有index做更新(非runtime字段)
- 所以刪除舊索引重建, 完整的定義如下
```
PUT /test_doc
{
? "mappings" : {
? ? "dynamic" : "runtime",
? ? "properties" : {
? ? ? "doc" : {
? ? ? ? "type" : "text",
? ? ? ? "fields" : {
? ? ? ? ? "synonym" : {
? ? ? ? ? ? "type" : "text",
? ? ? ? ? ? "analyzer":"my_synonym",
? ? ? ? ? ? "search_analyzer":"my_search_synonym"
? ? ? ? ? }
? ? ? ? }
? ? ? },
? ? ? "id" : {
? ? ? ? "type" : "long"
? ? ? }
? ? }
? },
? "settings": {
? ? "index": {
? ? ? "analysis": {
? ? ? ? "analyzer": {
? ? ? ? ? "my_synonym": {
? ? ? ? ? ? "tokenizer": "standard",
? ? ? ? ? ? "filter": [
? ? ? ? ? ? ? "lowercase",
? ? ? ? ? ? ? "asciifolding",
? ? ? ? ? ? ? "snowball",
? ? ? ? ? ? ? "synonym" ]
? ? ? ? ? },
? ? ? ? ? "my_search_synonym": {
? ? ? ? ? ? "tokenizer": "standard",
? ? ? ? ? ? "filter": [
? ? ? ? ? ? ? "lowercase",
? ? ? ? ? ? ? "asciifolding",
? ? ? ? ? ? ? "snowball",
? ? ? ? ? ? ? "synonym_graph" ]
? ? ? ? ? }
? ? ? ? },
? ? ? ? "filter": {
? ? ? ? ? "synonym": {
? ? ? ? ? ? "type": "synonym",
? ? ? ? ? ? "format": "wordnet",
? ? ? ? ? ? "synonyms_path": "dictionaries/synonyms.txt"
? ? ? ? ? },
? ? ? ? ? "synonym_graph": {
? ? ? ? ? ? "type": "synonym_graph",
? ? ? ? ? ? "format": "wordnet",
? ? ? ? ? ? "synonyms_path": "dictionaries/synonyms.txt"
? ? ? ? ? }
? ? ? ? }
? ? ? }
? ? }
? }
}
```
- 測(cè)試
```
PUT /test_doc/_doc/1
{
? "id": 1,
? "doc": "test doc 1 v2 someone"
}
GET /test_doc/_search
{
? "query": {
? ? "match": {
? ? ? "doc.synonym": "person"
? ? }
? }
}
```
? - 注意如果是針對(duì) doc字段(不是doc.synonym) 就沒(méi)有同義詞功能
# java應(yīng)用訪問(wèn)elasticsearch
- 解決一下secret的問(wèn)題
? - 即elasticsearch的用戶名和密碼
? - 參考 https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets
? - 在volumes下增加一個(gè)節(jié)點(diǎn)
? ? ```
? ? - name: elastic-user-volume
? ? ? secret:
? ? ? ? secretName: quickstart-es-elastic-user
? ? ```
? - 在pod的volumeMounts下增加一個(gè)節(jié)點(diǎn)
? ? ```
? ? - name: elastic-user-volume
? ? ? mountPath: /app/secret-elastic-user
? ? ? readOnly: true
? ? ```
? - 結(jié)果
? ? - pod增加了一個(gè)/app/secret-elastic-user目錄
? ? - 里面有一個(gè)名為 elastic 的文本文件
? ? - 內(nèi)容是密碼
? - 用spring boot properties讀取該密碼
? ? - 也可以把secret映射成env 環(huán)境變量
? ? - 采用自定義service的方法, 使用InitializingBean接口, 在afterPropertiesSet方法中主動(dòng)讀取密碼
- 直接采用java 11的httpclient發(fā)起對(duì)elasticsearch集群的請(qǐng)求
? - elastic search的原配客戶端用的不是java 11的http client
? - 怕有沖突
- 測(cè)試環(huán)境問(wèn)題
? - 使用port-forward
? - 服務(wù)名 service/quickstart-es-http
? - 端口 9200
? - 根據(jù)環(huán)境變量env決定使用測(cè)試的localhost還是集群內(nèi)部域名
? - 集群內(nèi)部域名為 quickstart-es-http:9200
- 構(gòu)造請(qǐng)求串的問(wèn)題
? - 不使用elasticsearch的客戶端 所以自己做json字符串
? - 使用String.format替換 因?yàn)?%s 不容易和json數(shù)據(jù)沖突
? - 未考慮注入問(wèn)題 線上使用必須加escape
- 用戶名密碼如何傳入的問(wèn)題
? - 參考 https://www.elastic.co/guide/en/elasticsearch/reference/current/http-clients.html#:~:text=The%20Elasticsearch%20security%20features%20work%20with%20standard%20HTTP,be%20sent%20with%20every%20request%3A%20Authorization%3A%20Basic%20%3CTOKEN%3E
? - 其實(shí)就是加個(gè)header 名字 Authorization
? - 取值 Basic <TOKEN>
? - 其中 <TOKEN> 是 base64(USERNAME:PASSWORD)
- 報(bào)錯(cuò)沒(méi)響應(yīng) 需要走h(yuǎn)ttps協(xié)議
? - url改為https開(kāi)頭
? - 報(bào)錯(cuò)自簽名證書問(wèn)題
? - 參考 https://stackoverflow.com/questions/1201048/allowing-java-to-use-an-untrusted-certificate-for-ssl-https-connection/1201102#1201102
? - 關(guān)掉自簽名證書
? - 報(bào)錯(cuò)域名校驗(yàn)問(wèn)題
? - 參考 https://stackoverflow.com/questions/52988677/allow-insecure-https-connection-for-java-jdk-11-httpclient
? - 關(guān)掉域名校驗(yàn)
- Postman直接測(cè)elasticsearch
? - 提前驗(yàn)證用戶名密碼驗(yàn)證的問(wèn)題
? - postman關(guān)掉ssl校驗(yàn)
? - 因?yàn)?200已經(jīng)port-forward出來(lái)了, 所以直接往這個(gè)地址發(fā)即可
- 用異步接口 加try catch exception
- 結(jié)果
? - 測(cè)試環(huán)境通過(guò)
- 后續(xù)問(wèn)題 TODO
? - 返回?cái)?shù)據(jù)解析
? - 發(fā)布驗(yàn)證