go做后端的网站,怎样建设淘宝客导购网站,手机传奇开服网,外贸网站建设优化营销提示#xff1a;文章写完后#xff0c;目录可以自动生成#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、类和接口介绍0.封装思想1.es的操作分类 二、创建索引1.成员变量2.构造函数2.添加字段3.发送请求4.创建索引总体代码 三.插入数据四.删除数据五.查询数据 前… 提示文章写完后目录可以自动生成如何生成可参考右边的帮助文档 文章目录 前言一、类和接口介绍0.封装思想1.es的操作分类 二、创建索引1.成员变量2.构造函数2.添加字段3.发送请求4.创建索引总体代码 三.插入数据四.删除数据五.查询数据 前言
es他使用的网络协议时http序列化协议用的json。而es客户端给我们提供的三个接口中我们需要填的就是一个请求正文所以我们主要是针对这个正文json的一个组织。 这里贴一个连接里面是一些请求格式: es基本请求格式 提示以下是本篇文章正文内容下面案例可供参考
一、类和接口介绍
0.封装思想
ES客户端API二次封装: 封装四个操作:索引创建数据新增数据查询数据删除 封装最主要要完成的是请求正文的构造过程: Json::Value 对象的数据新增过程 索引创建: 1.能够动态设定索引名称索引类型 2.能够动态的添加字段并设置字段类型 设置分词器类型是否构造索引 构造思想:根据固定的ison格式构造Value对象即可 数据新增: 1.提供用户一个新增字段及数据的接口即可 2.提供一个发起请求的接口
1.es的操作分类
对于ES的操作请求分类: 1.创建索引 2.新增数据 3. 查询数据 4.删除数据 下面是我们需要使用到的接口search是用于查询数据第二个index是用户索引创建和新增数据两个功能第三个接口是用于删除数据的。最后一个接口时创建一个客户端用于和es服务器进行通信。前面的三个接口都是这个client提供的。 上面的三个接口的返回值都是一个response对象这里是这个对象的定义有一个响应码和一个响应码描述。
二、创建索引
1.成员变量
这个类中有五个成员变量 name就是索引名,type就是一个类型我们这里的类型都填一个_doc. 第三个变量就是一个Json对象这个proerties就是我们要创建索引有哪些字段我们这里是以用户索引为例项目中用户的信息有用户昵称电话用户id个性签名头像Id。所以在我们的这个proerties中就要有这几个字段。这也是我们创建索引中最核心的部分。 第四个变量_index就是我们创建索引的总的一个json正文我们给服务器发送请求就是发送的这个json串。 第五个参数就是一个client我们需要通过这个对象给服务器发送请求。
std::string _name;
std::string _type;
Json::Value _properties;
Json::Value _index;
std::shared_ptrelasticlient::Client _client;2.构造函数
在构造函数中用户需要闯入两个参数一个就是一个client用户需要自己定义一个client然后闯入进来第二个就是你要创建的索引名。 在构造函数的函数体中主要是组织了settings部分的json。其中tokenizer是分词工具我们填入的是ik_max_work它可以支持中文分词。这里具体要看es操作的请求体进行分析。 后面复习看到这里记得看图 ESIndex(std::shared_ptrelasticlient::Client client, const std::string name, const std::string type _doc):_name(name), _type(type), _client(client) {Json::Value analysis;Json::Value analyzer;Json::Value ik;Json::Value tokenizer;tokenizer[tokenizer] ik_max_word;ik[ik] tokenizer;analyzer[analyzer] ik;analysis[analysis] analyzer;_index[settings] analysis;}2.添加字段
我们要创建的索引它里面有哪些字段比如用户索引就有用户id,昵称签名手机号等。如果是一个消息索引就有消息id消息时间消息体等。 用户需要指定key也就是哪一个字段。其中type就是字段的类型axalyzer就是分词工具enable是是否参与索引这里我们默认是true对于一些用户索引我们的用户昵称用户id,手机号是要参与索引的于是要设为true. 另外这个type如果设置为text就代表进行分词就需要设置分词工具type类型为keyword就代表不进行分词。另外这里我们这里对enable进行了一个判断,如果他为false,我们才添加到json中原因是es会默认添加enable:true。 ESIndex append(const std::string key, const std::string type text, const std::string analyzer ik_max_word, bool enabled true) {Json::Value fields;fields[type] type;fields[analyzer] analyzer;if (enabled false ) fields[enabled] enabled;_properties[key] fields;return *this;}3.发送请求
这里需要一个索引Id,防止对于同一个索引类型创建出多个索引这里我们有默认参数不许用户提供了。这里面就会对总的Json进行一个组织然后调用client的index进行一个请求发送。他会返回一个response对象我们根据这个对象里的响应码判断是否成功。需要对这个发送请求进行捕获在index内部如果失败会抛出异常。为了防止程序异常崩溃我们捕获一下。
bool create(const std::string index_id default_index_id) {Json::Value mappings;mappings[dynamic] true;mappings[properties] _properties;_index[mappings] mappings;std::string body;bool ret Serialize(_index, body);if (ret false) {LOG_ERROR(索引序列化失败);return false;}LOG_DEBUG({}, body);//2. 发起搜索请求try {auto rsp _client-index(_name, _type, index_id, body);if (rsp.status_code 200 || rsp.status_code 300) {LOG_ERROR(创建ES索引 {} 失败响应状态码异常: {}, _name, rsp.status_code);return false;}} catch(std::exception e) {LOG_ERROR(创建ES索引 {} 失败: {}, _name, e.what());return false;}return true;}4.创建索引总体代码
class ESIndex {public:ESIndex(std::shared_ptrelasticlient::Client client, const std::string name, const std::string type _doc):_name(name), _type(type), _client(client) {Json::Value analysis;Json::Value analyzer;Json::Value ik;Json::Value tokenizer;tokenizer[tokenizer] ik_max_word;ik[ik] tokenizer;analyzer[analyzer] ik;analysis[analysis] analyzer;_index[settings] analysis;}ESIndex append(const std::string key, const std::string type text, const std::string analyzer ik_max_word, bool enabled true) {Json::Value fields;fields[type] type;fields[analyzer] analyzer;if (enabled false ) fields[enabled] enabled;_properties[key] fields;return *this;}bool create(const std::string index_id default_index_id) {Json::Value mappings;mappings[dynamic] true;mappings[properties] _properties;_index[mappings] mappings;std::string body;bool ret Serialize(_index, body);if (ret false) {LOG_ERROR(索引序列化失败);return false;}LOG_DEBUG({}, body);//2. 发起搜索请求try {auto rsp _client-index(_name, _type, index_id, body);if (rsp.status_code 200 || rsp.status_code 300) {LOG_ERROR(创建ES索引 {} 失败响应状态码异常: {}, _name, rsp.status_code);return false;}} catch(std::exception e) {LOG_ERROR(创建ES索引 {} 失败: {}, _name, e.what());return false;}return true;}private:std::string _name;std::string _type;Json::Value _properties;Json::Value _index;std::shared_ptrelasticlient::Client _client;
};三.插入数据
插入请求的请求正文比较简单就是对你插入数据的个字段进行一个组织就行。例如用户信息索引就有昵称用户Id,签名电话等。我们把它组织到一个json中在这里成员变量定义了一个item进行组织。通过append函数进行组织。用户只需要填写key和val.例如nickname:“小明”。
class ESInsert {public:ESInsert(std::shared_ptrelasticlient::Client client, const std::string name, const std::string type _doc):_name(name), _type(type), _client(client){}templatetypename TESInsert append(const std::string key, const T val){_item[key] val;return *this;}bool insert(const std::string id ) {std::string body;bool ret Serialize(_item, body);if (ret false) {LOG_ERROR(索引序列化失败);return false;}LOG_DEBUG({}, body);//2. 发起搜索请求try {auto rsp _client-index(_name, _type, id, body);if (rsp.status_code 200 || rsp.status_code 300) {LOG_ERROR(新增数据 {} 失败响应状态码异常: {}, body, rsp.status_code);return false;}} catch(std::exception e) {LOG_ERROR(新增数据 {} 失败: {}, body, e.what());return false;}return true;}private:std::string _name;std::string _type;Json::Value _item;std::shared_ptrelasticlient::Client _client;
};四.删除数据
删除数据没有正文体只需要提供你要删除的索引类型以及一个文档id。
class ESRemove {
public:ESRemove(std::shared_ptrelasticlient::Client client, const std::string name, const std::string type _doc):_name(name), _type(type), _client(client){}bool remove(const std::string id) {try {auto rsp _client-remove(_name, _type, id);if (rsp.status_code 200 || rsp.status_code 300) {LOG_ERROR(删除数据 {} 失败响应状态码异常: {}, id, rsp.status_code);return false;}} catch(std::exception e) {LOG_ERROR(删除数据 {} 失败: {}, id, e.what());return false;}return true;}
private:std::string _name;std::string _type;std::shared_ptrelasticlient::Client _client;
};五.查询数据
查询这里我们需要添加一些过滤条件在es中有must_not/should/must/三个Json。分别代表必须不满足的条件可选满足条件必须满足条件。
class ESSearch {public:ESSearch(std::shared_ptrelasticlient::Client client, const std::string name, const std::string type _doc):_name(name), _type(type), _client(client){}ESSearch append_must_not_terms(const std::string key, const std::vectorstd::string vals) {Json::Value fields;for (const auto val : vals){fields[key].append(val);}Json::Value terms;terms[terms] fields;_must_not.append(terms);return *this;}ESSearch append_should_match(const std::string key, const std::string val) {Json::Value field;field[key] val;Json::Value match;match[match] field;_should.append(match);return *this;}ESSearch append_must_term(const std::string key, const std::string val) {Json::Value field;field[key] val;Json::Value term;term[term] field;_must.append(term);return *this;}ESSearch append_must_match(const std::string key, const std::string val){Json::Value field;field[key] val;Json::Value match;match[match] field;_must.append(match);return *this;}Json::Value search(){Json::Value cond;if (_must_not.empty() false) cond[must_not] _must_not;if (_should.empty() false) cond[should] _should;if (_must.empty() false) cond[must] _must;Json::Value query;query[bool] cond;Json::Value root;root[query] query;std::string body;bool ret Serialize(root, body);if (ret false) {LOG_ERROR(索引序列化失败);return Json::Value();}LOG_DEBUG({}, body);//2. 发起搜索请求cpr::Response rsp;try {rsp _client-search(_name, _type, body);if (rsp.status_code 200 || rsp.status_code 300) {LOG_ERROR(检索数据 {} 失败响应状态码异常: {}, body, rsp.status_code);return Json::Value();}} catch(std::exception e) {LOG_ERROR(检索数据 {} 失败: {}, body, e.what());return Json::Value();}//3. 需要对响应正文进行反序列化LOG_DEBUG(检索响应正文: [{}], rsp.text);Json::Value json_res;ret UnSerialize(rsp.text, json_res);if (ret false) {LOG_ERROR(检索数据 {} 结果反序列化失败, rsp.text);return Json::Value();}return json_res[hits][hits];}private:std::string _name;std::string _type;Json::Value _must_not;Json::Value _should;Json::Value _must;std::shared_ptrelasticlient::Client _client;
};
}