欢迎光临散文网 会员登陆 & 注册

学习日志 211230 elasticsearch同义词 从java端发起调用

2021-12-30 18:12 作者:mayoiwill  | 我要投稿

# 211230


## 继续搞同义词字典上传

- 上传文件给pod有以下几种方式

  - 使用configMap

    - 可共享 有大小限制 最多3M

  - 使用pvc

    - 不可共享 扩容的话需要手工对扩出来的pod再上传

  - 使用initContainers指令做curl

    - 不需要重复操作

    - 需要一个源

  - 提前做好docker image

    - 不需要重复操作

    - 比较麻烦

  - 综上 我们尝试一下initContainers

    - 源用内部nginx

    - 内部nginx上的文件 使用pvc cp的方式

- 搞一个内部nginx

  - 参考 https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/

  - 不写cpu和内存 看一下默认是多少

    - 全是0

  - port-forward 80 出错

    - 使用 `kubectl run -i --tty --image busybox:1.28 dns-test --restart=Never --rm /bin/sh`

    - 创建dns检查环境

    - 使用 nslookup mycluster-nginx-0.mycluster-nginx

    - 发现DNS不通 怀疑service有问题

    - 检查service发现 service的selector写错了

    - 修复后重新apply -f

    - 重新port-forward

    - 检查localhost:80 可以访问

  - 上传文件

    - 采用 kubectl cp指令

    - `kubectl cp .\synonym\synonyms.json mycluster-nginx-0:/usr/share/nginx/html`

    - 其中 /usr/share/nginx/html 目录是nginx读取的源目录

    - 也是pvc 挂载的目录

    - 测试 http://localhost/synonyms.json

- 让elasticsearch使用initContainers 将该文件copy到自己的运行环境

  - 指令格式

  - 前面的 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报格式不对

  - 修改同义词词典的格式

  - 不需要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的文件名

- 测试

```

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"

}

```

  - 结果 person 在wordnet中有6个同义词


## 应用分析器到索引

- 我们自己的`test_doc`原始字段只有`id``doc`

- 为doc字段建一个subfield叫做`doc.synonym`

- 先建对应的自定义analyzer

  - tokenizer standard

  - filter

    - lowercase

    - asciifolding

    - snowball

    - synonym

- 构建期采用synonym的filter, 搜索时则采用synonym_graph

- 由于不能针对已有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"

          }

        }

      }

    }

  }

}

```

- 测试

```

PUT /test_doc/_doc/1

{

  "id": 1,

  "doc": "test doc 1 v2 someone"

}

GET /test_doc/_search

{

  "query": {

    "match": {

      "doc.synonym": "person"

    }

  }

}

```

  - 注意如果是针对 doc字段(不是doc.synonym) 就没有同义词功能


# java应用访问elasticsearch

- 解决一下secret的问题

  - 即elasticsearch的用户名和密码

  - 参考 https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets

  - 在volumes下增加一个节点

    ```

    - name: elastic-user-volume

      secret:

        secretName: quickstart-es-elastic-user

    ```

  - 在pod的volumeMounts下增加一个节点

    ```

    - name: elastic-user-volume

      mountPath: /app/secret-elastic-user

      readOnly: true

    ```

  - 结果

    - pod增加了一个/app/secret-elastic-user目录

    - 里面有一个名为 elastic 的文本文件

    - 内容是密码

  - 用spring boot properties读取该密码

    - 也可以把secret映射成env 环境变量

    - 采用自定义service的方法, 使用InitializingBean接口, 在afterPropertiesSet方法中主动读取密码

- 直接采用java 11的httpclient发起对elasticsearch集群的请求

  - elastic search的原配客户端用的不是java 11的http client

  - 怕有冲突

- 测试环境问题

  - 使用port-forward

  - 服务名 service/quickstart-es-http

  - 端口 9200

  - 根据环境变量env决定使用测试的localhost还是集群内部域名

  - 集群内部域名为 quickstart-es-http:9200

- 构造请求串的问题

  - 不使用elasticsearch的客户端 所以自己做json字符串

  - 使用String.format替换 因为 %s 不容易和json数据冲突

  - 未考虑注入问题 线上使用必须加escape

- 用户名密码如何传入的问题

  - 参考 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

  - 其实就是加个header 名字 Authorization

  - 取值 Basic <TOKEN>

  - 其中 <TOKEN> 是 base64(USERNAME:PASSWORD)

- 报错没响应 需要走https协议

  - url改为https开头

  - 报错自签名证书问题

  - 参考 https://stackoverflow.com/questions/1201048/allowing-java-to-use-an-untrusted-certificate-for-ssl-https-connection/1201102#1201102

  - 关掉自签名证书

  - 报错域名校验问题

  - 参考 https://stackoverflow.com/questions/52988677/allow-insecure-https-connection-for-java-jdk-11-httpclient

  - 关掉域名校验

- Postman直接测elasticsearch

  - 提前验证用户名密码验证的问题

  - postman关掉ssl校验

  - 因为9200已经port-forward出来了, 所以直接往这个地址发即可

- 用异步接口 加try catch exception

- 结果

  - 测试环境通过

- 后续问题 TODO

  - 返回数据解析

  - 发布验证


学习日志 211230 elasticsearch同义词 从java端发起调用的评论 (共 条)

分享到微博请遵守国家法律