[C++][第三方库][Elasticsearch]详细讲授

打印 上一主题 下一主题

主题 804|帖子 804|积分 2412


1.介绍



  • Elasticsearch,简称ES,它是个开源分布式搜刮引擎

    • 特点:分布式,零配置,主动发现,索引主动分片,索引副本机制,restful风格接口,多数据源,主动搜刮负载等
    • 它可以近乎及时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据
    • ES也利用Java开发并利用Lucene作为其核心来实现所有索引和搜刮的功能,但是它的目标是通过简单的RESTfulAPI来隐蔽Lucene的复杂性,从而让全文搜刮变得简单

  • Elasticsearch是**面向文档**(document oriented)的

    • 这意味着它可以存储整个对象或文档(document)
    • 然而它不仅仅是存储,还会索引(index)每个文档的内容使之可以被搜刮

      • 可以对文档(而非成行成列的数据)举行索引、搜刮、排序、过滤



2.安装

1.ES



  • 添加堆栈密钥:上边的添加方式会导致一个apt-key的警告,假如不想报警告利用下边这个
    1. # 1.
    2. wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
    3. # 2.
    4. curl -s https://artifacts.elastic.co/GPG-KEY-elasticsearch | \
    5. sudo gpg --no-default-keyring \
    6. --keyring gnupg-ring:/etc/apt/trusted.gpg.d/icsearch.gpg --import
    复制代码
  • 添加镜像源堆栈
    1. echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" \
    2. | sudo tee /etc/apt/sources.list.d/elasticsearch.list
    复制代码
  • 更新软件包列表
    1. sudo apt update
    复制代码
  • 安装ES
    1. sudo apt-get install elasticsearch=7.17.21
    复制代码
  • 启动ES
    1. sudo systemctl start elasticsearch
    复制代码
  • 安装ik分词器插件
    1. sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install \
    2. https://get.infini.cloud/elasticsearch/analysis-ik/7.17.21
    复制代码
  • 检察ES服务的状态
    1. sudo systemctl status elasticsearch.service
    复制代码
  • 验证ES是否安装乐成
    1. curl -X GET "http://localhost:9200/"
    复制代码
  • 设置外网访问:默认只能在本机举行访问,修改后欣赏器访问IPORT
    1. vim /etc/elasticsearch/elasticsearch.yml
    2. # 新增配置
    3. network.host: 0.0.0.0
    4. http.port: 9200
    5. cluster.initial_master_nodes: ["node-1"]
    复制代码
  • 假如启动ES的时间出现报错

    • 解决方法
      1. # 调整ES虚拟内存,虚拟内存默认最大映射数为65530,无法满足ES系统要求, 需要调整为262144以上
      2. sudo sysctl -w vm.max_map_count=262144
      3. # 增加虚拟机内存配置
      4. sudo vim /etc/elasticsearch/jvm.options
      5. # 新增如下内容
      6. -Xms512m
      7. -Xmx512m
      复制代码
      1. Job for elasticsearch.service failed because the control process exited with error code.
      2. See "systemctl status elasticsearch.service" and "journalctl -xeu elasticsearch.service" for details.
      复制代码


2.Kibana



  • 安装Kibana
    1. sudo apt install kibana
    复制代码
  • 配置Kibana(可选):根据须要配置Kibana,配置文件通常位于/etc/kibana/kibana.yml,可能须要设置如服务器地址、端口、Elasticsearch URL等
  • 启动Kibana
    1. sudo systemctl start kibana
    复制代码
  • 设置开机自启(可选)
    1. sudo systemctl enable kibana
    复制代码
  • 访问Kibana:http://<ip>:5601

3.ES核心概念

1.索引(index)



  • 一个索引就是一个拥有几分相似特性的文档的聚集

    • 比方

      • 有一个客户数据的索引,一个产物目次的索引,另有一个订单数据的索引
      • 一个索引由一个名字来标识(必须全部是小写字母的),并且当要对应于这个索引中的文档举行索引、搜刮、更新和删除的时间,都要利用到这个名字


  • 在一个集群中,可以定义任意多的索引
  • 索引类似于数据库中的概念

    • 数据库中的库,表示了一组数据的聚集
    • ES中的索引,是一组相似特性数据的聚集


2.类型(Type)



  • 在一个索引中,可以定义一种或多种类型
  • 一个类型是索引的一个逻辑上的分类/分区,其语义完全由用户来定
  • 通常,会为具有一组共同字段的文档定义一个类型

    • 比方

      • 运营一个博客平台并且将所有的数据存储到一个索引中
      • 在这个索引中,可以为用户数据定义一个类型,为博客数据定义另一个类型,为评论数据定义另一个类型


  • [类型]类似于数据库中表的概念,在索引的概念下,又对数据聚集举行了一层细分
  • 现在[类型]几乎已经弃用

3.字段(Field)



  • 字段相当于是数据库表的字段,对文档数据根据不同属性举行的分类标识 -> 数据类型
    ![[Pasted image 20240918180030.png]]

4.映射(mapping)



  • 映射是在处理数据的方式和规则方面做一些限定

    • 某个字段的数据类型、默认值、分析器、是否被索引等等,这些都是映射里面可以设置的

      • 映射类似于告诉ES哪些字段须要分词,做出索引映射,可以大概举行数据检索

    • 别的就是处理ES里面数据的一些利用规则设置也叫做映射

  • 按着最优规则处理数据对性能进步很大,因此才须要建立映射,并且须要思考如何建立映射才能对性能更好
  • 详细规则

    • enabled:是否仅作存储,不做搜刮和分析

      • 取值:true(默认)/false

    • index:是否构建倒排索引(决定了是否分词,是否被索引)

      • 取值:true(默认)/false

    • index_option
    • dynamic:控制mapping的主动更新

      • 取值:true(默认)/false

    • doc_value:是否开启doc_value,用户聚合和排序分析,分词字段不能利用

      • 取值:true(默认)/false

    • fielddata:是否为text类型启动fielddata,实现排序和聚合分析

      • 针对分词字段,参与排序或聚合时能进步性能
      • 不分词字段统一发起利用doc_value
        1. fielddata": {
        2.     "format": "disabled"
        3. }
        复制代码

    • store:是否单独设置此字段的是否存储而从_source字段中分离

      • 取值:true/false(默认)

    • coerce:是否开启主动数据类型转换功能,如字符串转整形,浮点转整形

      • 取值:true(默认)/false

    • analyzer:指定分词器,默认分词器是standard analyzer

      • 示例:”analyzer”: “ik”

    • boost:字段级别的分数加权,默认值是1.0

      • 示例:”boost”: 1.25

    • fields:对一个字段提供多种索引模式,同一个字段的值,一个分词一个不分词
      1. "fields": {
      2.     "raw": {
      3.         "type": "text",  
      4.         "index": "not_analyzed"
      5.     }
      6. }
      复制代码
    • data_detection:是否主动识别日期类型

      • 取值:true(默认)/false



5.文档(document)



  • 一个文档是一个可被索引的基础信息单元
  • 比方:某一个客户的文档,某一个产物的一个文档大概某个订单的一个文档

    • 文档以JSON格式来表示,而JSON是一个到处存在的互联网数据交互格式
    • 在一个index/type里面,可以存储任意多的文档
    • 一个文档必须被索引大概赋予一个索引的type

  • Elasticsearch与传统关系性数据库相比
       DBDatabaseTableRowColumnESIndexTypeDocumentField

4.Kibana访问ES举行测试



  • 创建索引库
    1. POST /user/_doc
    2. {
    3.     "settings" : {
    4.         "analysis" : {
    5.             "analyzer" : {
    6.                 "ik" : {
    7.                     "tokenizer" : "ik_max_word"
    8.                 }
    9.             }
    10.         }
    11.     },
    12.     "mappings" : {
    13.         "dynamic" : true,
    14.         "properties" : {
    15.             "nickname" : {
    16.                 "type" : "text",
    17.                 "analyzer" : "ik_max_word"
    18.             },
    19.             "user_id" : {
    20.                 "type" : "keyword",
    21.                 "analyzer" : "standard"
    22.             },
    23.             "phone" : {
    24.                 "type" : "keyword",
    25.                 "analyzer" : "standard"
    26.             },
    27.             "description" : {
    28.                 "type" : "text",
    29.                 "enabled" : false
    30.             },
    31.             "avatar_id" : {
    32.                 "type" : "keyword",
    33.                 "enabled" : false
    34.             }
    35.         }
    36.     }
    37. }
    复制代码
  • 新增数据

    • 插入形式
      1. POST /user/_doc/_bulk
      2. {"index":{"_id":"1"}}
      3. {"user_id" : "USER4b862aaa-2df8654a-7eb4bb65e3507f66","nickname" : "昵称1","phone" : "手机号1","description" : "签名1","avatar_id" : "头像1"}
      4. {"index":{"_id":"2"}}
      5. {"user_id" : "USER14eeeaa5-442771b9-0262e455e4663d1d","nickname" : "昵称2","phone" : "手机号2","description" : "签名2","avatar_id" : "头像2"}
      6. {"index":{"_id":"3"}}
      7. {"user_id" : "USER484a6734-03a124f0-996c169dd05c1869","nickname" : "昵称3","phone" : "手机号3","description" : "签名3","avatar_id" : "头像3"}
      8. {"index":{"_id":"4"}}
      9. {"user_id" : "USER186ade83-4460d4a6-8c08068f83127b5d","nickname" : "昵称4","phone" : "手机号4","description" : "签名4","avatar_id" : "头像4"}
      10. {"index":{"_id":"5"}}
      11. {"user_id" : "USER6f19d074-c33891cf-23bf5a8357189a19","nickname" : "昵称5","phone" : "手机号5","description" : "签名5","avatar_id" : "头像5"}
      12. {"index":{"_id":"6"}}
      13. {"user_id" : "USER97605c64-9833ebb7-d045535335a59195","nickname" : "昵称6","phone" : "手机号6","description" : "签名6","avatar_id" : "头像6"}
      复制代码
    • 便于阅读
      1. [
      2.     {
      3.         "index": {
      4.             "_id": "1"
      5.         },
      6.         "user": {
      7.             "user_id": "USER4b862aaa-2df8654a-7eb4bb65e3507f66",
      8.             "nickname": "昵称1",
      9.             "phone": "手机号1",
      10.             "description": "签名1",
      11.             "avatar_id": "头像1"
      12.         }
      13.     },
      14.     {
      15.         "index": {
      16.             "_id": "2"
      17.         },
      18.         "user": {
      19.             "user_id": "USER14eeeaa5-442771b9-0262e455e4663d1d",
      20.             "nickname": "昵称2",
      21.             "phone": "手机号2",
      22.             "description": "签名2",
      23.             "avatar_id": "头像2"
      24.         }
      25.     },
      26.     {
      27.         "index": {
      28.             "_id": "3"
      29.         },
      30.         "user": {
      31.             "user_id": "USER484a6734-03a124f0-996c169dd05c1869",
      32.             "nickname": "昵称3",
      33.             "phone": "手机号3",
      34.             "description": "签名3",
      35.             "avatar_id": "头像3"
      36.         }
      37.     },
      38.     {
      39.         "index": {
      40.             "_id": "4"
      41.         },
      42.         "user": {
      43.             "user_id": "USER186ade83-4460d4a6-8c08068f83127b5d",
      44.             "nickname": "昵称4",
      45.             "phone": "手机号4",
      46.             "description": "签名4",
      47.             "avatar_id": "头像4"
      48.         }
      49.     },
      50.     {
      51.         "index": {
      52.             "_id": "5"
      53.         },
      54.         "user": {
      55.             "user_id": "USER6f19d074-c33891cf-23bf5a8357189a19",
      56.             "nickname": "昵称5",
      57.             "phone": "手机号5",
      58.             "description": "签名5",
      59.             "avatar_id": "头像5"
      60.         }
      61.     },
      62.     {
      63.         "index": {
      64.             "_id": "6"
      65.         },
      66.         "user": {
      67.             "user_id": "USER97605c64-9833ebb7-d045535335a59195",
      68.             "nickname": "昵称6",
      69.             "phone": "手机号6",
      70.             "description": "签名6",
      71.             "avatar_id": "头像6"
      72.         }
      73.     }
      74. ]
      复制代码

  • 检察并搜刮数据:
    1. GET /user/_doc/_search?pretty
    2. {
    3.     "query" : {
    4.         "bool" : {
    5.             "must_not" : [
    6.                 {
    7.                     "terms" : {
    8.                         "user_id.keyword" : [
    9.                             "USER4b862aaa-2df8654a-7eb4bb65e3507f66",
    10.                             "USER14eeeaa5-442771b9-0262e455e4663d1d",
    11.                             "USER484a6734-03a124f0-996c169dd05c1869"
    12.                         ]
    13.                     }
    14.                 }
    15.             ],
    16.             "should" : [
    17.                 {
    18.                     "match" : {
    19.                         "user_id" : "昵称"
    20.                     }
    21.                 },
    22.                 {
    23.                     "match" : {
    24.                         "nickname" : "昵称"
    25.                     }
    26.                 },
    27.                 {
    28.                     "match" : {
    29.                         "phone" : "昵称"
    30.                     }
    31.                 }
    32.             ]
    33.         }
    34.     }
    35. }
    复制代码
  • 删除索引
    1. DELETE /user
    复制代码
  • 查询所有数据
    1. POST /user/_doc/_search
    2. {
    3.     "query":
    4.     {
    5.         "match_all":{}
    6.     }
    7. }
    复制代码

5.ES客户端的安装



  • 代码
  • 官网
  • ES C++的客户端选择并不多, 这里利用elasticlient库
  • 前置安装:依靠MicroHTTPD库
    1. sudo apt-get install libmicrohttpd-dev
    复制代码
  • 安装
    1. # 克隆代码
    2. git clone https://github.com/seznam/elasticlient
    3. # 切换目录
    4. cd elasticlient
    5. # 更新子模块
    6. git submodule update --init --recursive
    7. # 编译代码
    8. make build && cd build
    9. cmake ..
    10. make
    11. # 安装
    12. make install
    复制代码

6.ES客户端接口介绍

  1. /**
  2. * Perform search on nodes until it is successful. Throws
  3. exception if all nodes
  4. * has failed to respond.
  5. * \param indexName specification of an Elasticsearch index.
  6. * \param docType specification of an Elasticsearch document type.
  7. * \param body Elasticsearch request body.
  8. * \param routing Elasticsearch routing. If empty, no routing has
  9. been used.
  10. *
  11. * \return cpr::Response if any of node responds to request.
  12. * \throws ConnectionException if all hosts in cluster failed to
  13. respond.
  14. */
  15. cpr::Response search(const std::string &indexName,
  16.                      const std::string &docType,
  17.                      const std::string &body,
  18.                      const std::string &routing = std::string());
  19. /**
  20. * Get document with specified id from cluster. Throws exception
  21. if all nodes
  22. * has failed to respond.
  23. * \param indexName specification of an Elasticsearch index.
  24. * \param docType specification of an Elasticsearch document type.
  25. * \param id Id of document which should be retrieved.
  26. * \param routing Elasticsearch routing. If empty, no routing has
  27. been used.
  28. *
  29. * \return cpr::Response if any of node responds to request.
  30. * \throws ConnectionException if all hosts in cluster failed to
  31. respond.
  32. */
  33. cpr::Response get(const std::string &indexName,
  34.                   const std::string &docType,
  35.                   const std::string &id = std::string(),
  36.                   const std::string &routing = std::string());
  37. /**
  38. * Index new document to cluster. Throws exception if all nodes
  39. has failed to respond.
  40. * \param indexName specification of an Elasticsearch index.
  41. * \param docType specification of an Elasticsearch document type.
  42. * \param body Elasticsearch request body.
  43. * \param id Id of document which should be indexed. If empty, id
  44. will be generated
  45. *           automatically by Elasticsearch cluster.
  46. * \param routing Elasticsearch routing. If empty, no routing has
  47. been used.
  48. *
  49. * \return cpr::Response if any of node responds to request.
  50. * \throws ConnectionException if all hosts in cluster failed to
  51. respond.
  52. */
  53. cpr::Response index(const std::string &indexName,
  54.                     const std::string &docType,
  55.                     const std::string &id,
  56.                     const std::string &body,
  57.                     const std::string &routing = std::string());
  58. /**
  59. * Delete document with specified id from cluster. Throws
  60. exception if all nodes
  61. * has failed to respond.
  62. * \param indexName specification of an Elasticsearch index.
  63. * \param docType specification of an Elasticsearch document type.
  64. * \param id Id of document which should be deleted.
  65. * \param routing Elasticsearch routing. If empty, no routing has
  66. been used.
  67. *
  68. * \return cpr::Response if any of node responds to request.
  69. * \throws ConnectionException if all hosts in cluster failed to
  70. respond.
  71. */
  72. cpr::Response remove(const std::string &indexName,
  73.                      const std::string &docType,
  74.                      const std::string &id,
  75.                      const std::string &routing = std::string());
复制代码

7.利用



  • ES客户端利用注意

    • 地址后边不要忘了相对根目次:http://127.0.0.1:9200/
    • ES客户端API利用时,要举行异常捕捉,否则操纵失败会导致程序异常退出
    1. #include <iostream>
    2. #include <elasticlient/client.h>
    3. #include <cpr/cpr.h>
    4. int main()
    5. {
    6.     // 1.构造ES客户端
    7.     elasticlient::Client client({"http://127.0.0.1:9200/"});
    8.     // 2.发起搜索请求
    9.     try
    10.     {
    11.         auto resp = client.search("user", "_doc",
    12.                                                               "{"query": { "match_all":{} }}");
    13.         std::cout << resp.status_code << std::endl;
    14.         std::cout << resp.text << std::endl;
    15.     }
    16.     catch(std::exception &e)
    17.     {
    18.         std::cout << e.what() << std::endl;
    19.         return -1;
    20.     }
    21.     return 0;
    22. }
    复制代码



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

惊落一身雪

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表