码迷,mamicode.com
首页 > 编程语言 > 详细

为elasticSearch开发c++接口

时间:2018-08-14 17:08:18      阅读:277      评论:0      收藏:0      [点我收藏+]

标签:.com   过滤   概念   test   use   bin   第四部分   const   写入   

一、    ElasticSearch是什么

ElasticSearch是目前开源全文搜索引擎的首选,可以快速存储,搜索和分析海量数据。Stack Overflow,Github等都在使用。

Elasticsearch 是使用 Java 编写的,它的内部使用 Lucene 做索引与搜索,但是它使全文检索变得简单, 通过隐藏 Lucene 的复杂性,取而代之的提供一套简单一致的 RESTful API。

    ES提供的Client API:https://www.elastic.co/guide/en/elasticsearch/client/index.html

包含多种语言:

技术分享图片

技术分享图片

注意:没有C++接口,而我们需要基于c++操作ES

二、    安装部署

1.   服务器选择

设备IP:10.3.246.224

系统:linux-64

磁盘空间:无  (df –h 发现磁盘没容量了)

2.   解决磁盘占满

du -sh /* | sort –nr  :找出系统中占容量最大的文件夹,系统中15scpp这个文件夹占41G

 

du -sh /15scpp/* | sort -nr  :找出15scpp中占容量最大文件夹15scpp_testbin,占31G

 

确认这个文件夹已无用,rm删除

 

PS:在Linux中,当我们使用rm在linux上删除了大文件,但是如果有进程打开了这个大文件,却没有关闭这个文件的句柄,那么linux内核还是不会释放这个文件的磁盘空间。找出文件使用进程,kill掉,即可

3.   JDK8安装

Elastic 需要 Java 8 环境

Java –version查看java是否安装或现在版本

官网下载jdk-8u181-linux-x64.tar.gz,解压,安装,设置环境变量,这里就不赘述。

1.   下载ES

下载https://www.elastic.co/downloads/elasticsearch :

elasticsearch-6.3.2.tar.gz

tar解压

 

2.   创建新用户

因为安全问题elasticsearch 不让用root用户直接运行,所以要创建新用户:

adduser pwrd-es

passwd pwrd-es pwrd-es

3.   修改安装文件权限

chown -R pwrd-es:pwrd-es /home/elasticSearch/elasticsearch-6.3.2

//因为安全问题,不让root用户执行安装,但是其他用户又没有文件操作权限,故而改之

4.  修改ES配置

Vim config/elasticSearch.yml

cluster.name: pwrd-es   //Elasticsearch会自动发现在同一网段下的Elasticsearch 节点,用这个属性来区分不同的集群,cluster.name相同则自动组建成一个集群

node.name: node-1   //节点名,默认随机指定一个name列表中名字,不能重复

node.master: true      //指定该节点是否有资格被选举成为node,默认是true,es是默认集群中的第一台机器为master,如果这台机挂了就会重新选举master

node.data: true  //指定该节点是否存储索引数据,默认为true

path.data: /home/elasticSearch/log_export/data   //存储数据

path.logs: /home/elasticSearch/log_export/logs   //存储日志

network.host: 10.3.246.224    //设置成0.0.0.0 在curl中可以用localhost

http.port: 9200               //监听端口

index.number_of_shards: 5 // 设置默认索引分片个数,默认为5片

index.number_of_replicas: 1 //设置默认索引副本个数,默认为1个副本

5.   修改系统最大虚拟内存

vim /etc/sysctl.conf

vm.max_map_count = 655360

sysctl -p

 

6.   切换用户执行程序

切换用户: su pwrd-es

./elasticsearch

 

 

7.   验证安装效果

浏览器中输入10.3.246.224:9200

或者

curl ‘http://localhost:9200/?pretty‘   

可以看到一个json数据,即为安装成功

PS:pretty是为了json格式化,以至于返回的结果好看一些

一、    基本概念

1.   Node 与 Cluster

Elastic 本质上是一个分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个 Elastic 实例。

单个 Elastic 实例称为一个节点(node)。一组节点构成一个集群(cluster)

通过cluster.name 属性配置集群的名字,用于唯一标识一个集群,不同的集群,其cluster.name 不同,集群名字相同的所有节点自动组成一个集群。当启动一个结点时,该结点会在当前局域网内自动寻找相同集群名字的主结点;如果找到主结点,该结点加入集群中;如果未找到主结点,该结点成为主结点

2.   Index

ES基本结构是 : index/type/id -> document (一般以json样式存储数据)

所以Index(索引)是Elastic 数据管理的顶层单位,它是单个数据库的同义词。

ES会索引所有字段,经过处理后写入一个反向索引(Inverted Index)。查找数据的时候,直接查找该索引。

PS:每个 Index (即数据库)的名字必须是小写。

 

可以用如下命令,查看当前节点索引:

curl -X GET ‘http://localhost:9200/_cat/indices?v‘

3.   Document

Index里面单条的记录称为 Document(文档)。许多条 Document 构成了一个 Index。

Document 使用 JSON 格式表示,如下:

{

    “name”:”张三”,

     “age”:18,

     “sex”:”male”

}

PS:对于json的编写与格式是否正确,可以借助在线json工具:http://www.bejson.com/

4.   Type

Type可以用来分类document,比如,china/Beijing/id-i ->doc-n

china/shanghai/id-j ->doc-m

同一个Index下不同的 Type 应该有相似的结构。

但是,Elastic 6.x 版只允许每个 Index 包含一个 Type,7.x 版将会彻底移除 Type。

我们部署的是当前最新6.3.2版本

 

 

5.   Shared分片

当一个索引下的数据太多,超过单一节点所能提供的磁盘空间,ES提供分片功能,可以将海量数据分片存储到集群中不同的节点中。当你查询的索引分布在多个分片上时,ES会把查询发送给每个相关的分片,并将结果组合在一起,而应用程序并不知道分片的存在。即:这个过程对用户来说是透明的。

 

6.   Replicas副本

为提高查询吞吐量或实现高可用性,可以使用分片副本。

副本是一个分片的精确复制,每个分片可以有零个或多个副本。ES中可以有许多相同的分片,其中之一被选择更改索引操作,这种特殊的分片称为主分片。

当主分片丢失时,如:该分片所在的数据不可用时,集群将副本提升为新的主分片。

 

7.  ES数据架构概念与Mysql对比

 

技术分享图片

但是目前type即将作废。

四、    CRUD简介

1.   创建索引

curl -XPUT "http://10.3.246.224:9200/tests/"

返回数据

{

       "acknowledged": true,

       "shards_acknowledged": true,

       "index": "testes"

}

2.   添加数据

curl -XPUT "http://10.3.246.224:9200/tests/songs/1" -d ‘{"name":"deck the halls","year":"2018","month":"8"}‘ 会报错,如下指定header就可以了

 

curl -H "Content-Type: application/json" -XPUT "http://10.3.246.224:9200/tests/songs/1" -d ‘{"name":"deck the halls","year":"2018","month":"8"}‘

 

返回结果:

{

       "_index": "testes",

       "_type": "songs",

       "_id": "1",      //id 也可以不知道,由系统自主生成

       "_version": 1,

       "result": "created",//代表添加成功

       "_shards": {

              "total": 2,

              "successful": 1,

              "failed": 0

       },

       "_seq_no": 0,

       "_primary_term": 1

}

3.   读取数据

curl -XGET http://localhost:9200/music/songs/1?pretty

 

返回数据:

{

  "_index" : "testes",

  "_type" : "songs",

  "_id" : "1",

  "_version" : 1,

  "found" : true,  //查找成功

  "_source" : {    //目的数据

    "name" : "deck the halls",

    "year" : "2018",

    "month" : "8"

  }

}

 

 

4.   更新数据

a)   查找更新某个key:

curl -H "Content-Type: application/json" -XPOST "http://10.3.246.224:9200/testes/songs/1/_update?pretty" -d ‘{"doc":{"query":{"match":{"name":"qqqddd"}}}}‘

返回数据:

{

  "_index" : "testes",

  "_type" : "songs",

  "_id" : "1",

  "_version" : 2,

  "result" : "updated",//更新成功

  "_shards" : {

    "total" : 2,

    "successful" : 1,

    "failed" : 0

  },

  "_seq_no" : 1,

  "_primary_term" : 1

}

b)   更新整条数据:

curl -H "Content-Type: application/json" -XPOST "http://10.3.246.224:9200/testes/songs/1/_update?pretty" -d ‘{"doc":{"name":"qddd","year":"2018","month":"8"}}‘

返回数据同上

 

c)   还有就是用添加数据的命令:只是将数据改了

curl -H "Content-Type: application/json" -XPUT "http://10.3.246.224:9200/tests/songs/1" -d ‘{"name":"deck the halls","year":"2020","month":"8"}‘

5.   删除数据

curl -XDELETE "http://localhost:9200/music/songs/1"

 

返回数据:

{

       "_index": "tests",

       "_type": "songs",

       "_id": "1",

       "_version": 2,

       "result": "deleted",//删除成功

       "_shards": {

              "total": 2,

              "successful": 1,

              "failed": 0

       },

       "_seq_no": 1,

       "_primary_term": 1

}

注意:删除一个文档不会立即生效,它只是被标记成已删除。es将会在你之后添加更多索引的时候才会在后台进行删除内容的清理

五、    ES的C++ API开发

1.   ES没有C++的接口,而我们需要基于c++操作ES

有两个办法

一是嵌入其他语言的开发,利用ES已提供的接口,比如,在C++中嵌入python API,这在编译上可能引入新的问题

二是需要自己构造如第四部分的http请求来获得数据,可以基于libcurl库,也可以基于系统中已有的httpproxy

为了不破坏已有系统的一致性,基于httpproxy,来构造http请求,对外封装提供C++接口

2.    基于业务需求设计思想

/*es是面向文档,基于索引的弹性搜索引擎,故而

    *es中的数据结构:index/type/id ->对应一条数据,所以

*es中帖子的数据结构设计:

uid/tiezi/tid -> json{uid,tid,content,timestamp}

    *虽然存在uid和tid的冗余,但是这样设计的好处是:可以很方便处理某个人某条数据,因为uid就是索引,这样还利用了,索引的高处理性能

    */

3.    C++ API

1)   添加

/*功能:向es中添加protobuf数据,但是在es中是以json样式存在

    *uid:用户id

    *tid:帖子id

    *msg:帖子结构,即(uid,tid,content,timestamp)

    */

bool addDocument(const std::string &uid, const std::string &tid,const google::protobuf::Message *msg);

封装后形成的http请求:

curl -H "Content-Type: application/json" -XPUT "http://10.3.246.224:9200/ uid /tiezi/tid " -d ‘ msg .json_str()‘

 

2)   删除

    /*功能:向es中删除某个人uid的所有数据

    *uid:用户id

    */

bool deleteAllByUid(const std::string &uid);

封装后形成的http请求:

curl -XDELETE http://localhost:9200/uid  -d ‘{“query”:{“match_all”:{}}}’

 

    /*功能:向es中删除某个人具体的某个数据

    *uid:用户id

    *tid:帖子id

    */

bool deleteDocumentByUidTid(const std::string &uid, const std::string &tid);

封装后形成的http请求:

curl -XDELETE "http://localhost:9200/ uid / tiezi / tid "

 

    /*功能:向es中删除某个用户某个时间点以前的所有帖子,也就是 小于 某个时间的所有帖子

    *uid:用户id

    *beforeTimes:时刻以前的数据将全部会删除

    */

bool deleteDocumentByUidBeforeTimes(const std::string &uid, const std::string &beforeTimes);

封装后形成的http请求:

curl -XPOST "http://localhost:9200/ uid /tiezi/_delete_by_query

-d‘{"query":{"range":{"timestamp.keyword":{"gte":"2016-07-09 11:18:21","lte":"2018-08-17 11:18:21","format":"yyyy-MM-dd HH:mm:ss"}}}}’

 

PS: timestamp是数据中一个字段,在时间段匹配中,要注意空格

3)   查询

    /*功能:以或的逻辑关系操作查询帖子中是否存在包含词,并过滤返回结果,只返回并得到UID,tid

    *注:比如查询词是词组:"running swimming",查询之后的结果是,只要帖子content中至少包含一个词汇就可以,即帖子content中包含"running","swimming","running ... swimming ..."都返回

    *containsWords:查询词 或词组 ,比如 "sport","running swimming"

    *uid_tid:查询成功返回的N条uid和tid数据

    */

int searchAllByContainWords_OR(const std::string &containsWords,vector<struct Uid_Tid> &uid_tid);

封装后形成的http请求:

curl -H "Content-Type: application/json" -XPOST "http://localhost:9200/_search

-d ‘{"query":{"match": {"content":{"query":"swimming running"","operator":"or"}}},"_source":["uid","tid"]}’

 

PS: operator 是or,表示是或逻辑操作,query中填写多个字段,匹配数据字段content中存在swimming或running,_source 中有数据字段uid和tid,用来控制返回结果的,当数据量很大的时候对结果裁剪,减少无用的数据传输

 

 

    /*功能:以与的逻辑关系操作查询帖子中是否存在包含词,并过滤返回结果,只返回并得到UID,tid

    *注:比如查询词是词组:"running swimming",查询之后的结果是,帖子content中包含每个词汇,即帖子content中包含running和 swimming才返回

    *containsWords:查询词 或词组 ,比如 "sport","running swimming"

    *uid_tid:查询成功返回的N条uid和tid数据

    */

    Int searchAllByContainWords_AND(const std::string &containsWords,vector<struct Uid_Tid> &uid_tid);

封装后形成的http请求:

curl -H "Content-Type: application/json" -XPOST "http://localhost:9200/_search

-d ‘{"query":{"match": {"content":{"query":"swimming running"","operator":"and"}}},"_source":["uid","tid"]}’

 

PS:同上,区别是operator是and,表示是与逻辑操作

 

 

 类似c++ API接口参考:https://github.com/QHedgeTech/cpp-elasticsearch

六、    资料

1.   ES参考手册

https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html

2.   《ElasticSearch权威指南》

https://www.elastic.co/guide/cn/elasticsearch/guide/current/intro.html

 

3.   中文社区

https://elasticsearch.cn/

4.   英文社区

https://discuss.elastic.co/c/elasticsearch/

 

七、    插件

1.   Head插件

在chrome中直接安装的插件,要比在linux下命令安装简单

 

2.   Ik分词插件

 

八、    其他

ES也提供对数据的分析,功能非常强大,还有很多像ik这样分词插件,我们在浏览器中访问es服务,在web界面中也可以很方便的操作数据。了解的非常浅显,暂记于此,以待有机会深入了解。对于json格式以及json中数据空格也需要非常注意。

 

为elasticSearch开发c++接口

标签:.com   过滤   概念   test   use   bin   第四部分   const   写入   

原文地址:https://www.cnblogs.com/woshare/p/9475379.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!