1.介绍
- ,简称 ES,它是个开源分布式搜索引擎
本文介绍了 Elasticsearch(ES)分布式搜索引擎的基本概念、安装配置及核心术语。内容包括 ES 与 Kibana 的安装步骤、索引、类型、字段、映射及文档等核心概念。重点讲解了 C++ 客户端 elasticlient 的使用,涵盖环境搭建、接口说明及代码示例,展示了如何通过 C++ 进行数据的增删改查操作。

ElasticsearchRESTful风格接口,多数据源,自动搜索负载等PB级别的数据ES也使用 Java 开发并使用 Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的 RESTfulAPI 来隐藏 Lucene的复杂性,从而让全文搜索变得简单Elasticsearch是面向文档(document oriented)的
document)index)每个文档的内容使之可以被搜索
解决方法:
# 调整 ES 虚拟内存,虚拟内存默认最大映射数为 65530,无法满足 ES 系统要求,需要调整为 262144 以上
sudo sysctl -w vm.max_map_count=262144
# 增加虚拟机内存配置
sudo vim /etc/elasticsearch/jvm.options
# 新增如下内容
-Xms512m
-Xmx512m
Job for elasticsearch.service failed because the control process exited with error code. See "systemctl status elasticsearch.service" and "journalctl -xeu elasticsearch.service" for details.
设置外网访问:默认只能在本机进行访问,修改后浏览器访问 IP:PORT
vim /etc/elasticsearch/elasticsearch.yml
# 新增配置
network.host: 0.0.0.0
http.port: 9200
cluster.initial_master_nodes: ["node-1"]
验证 ES 是否安装成功:
curl -X GET "http://localhost:9200/"
查看 ES 服务的状态:
sudo systemctl status elasticsearch.service
安装 ik分词器插件:
sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install https://get.infini.cloud/elasticsearch/analysis-ik/7.17.21
启动 ES:
sudo systemctl start elasticsearch
安装 ES:
sudo apt-get install elasticsearch=7.17.21
更新软件包列表:
sudo apt update
添加镜像源仓库:
echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elasticsearch.list
添加仓库密钥:上边的添加方式会导致一个 apt-key的警告,如果不想报警告使用下边这个
# 1.wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
# 2.curl -s https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/icsearch.gpg --import
Kibana,配置文件通常位于 /etc/kibana/kibana.yml,可能需要设置如服务器地址、端口、Elasticsearch URL等http://<ip>:5601**设置开机自启 **(可选):
sudo systemctl enable kibana
启动 Kibana:
sudo systemctl start kibana
安装 Kibana:
sudo apt install kibana
enabled:是否仅作存储,不做搜索和分析
true(默认)/falseindex:是否构建倒排索引 (决定了是否分词,是否被索引)
true(默认)/falseindex_optiondynamic:控制 mapping的自动更新
true(默认)/falsedoc_value:是否开启 doc_value,用户聚合和排序分析,分词字段不能使用
true(默认)/falsefielddata:是否为 text类型启动 fielddata,实现排序和聚合分析
store:是否单独设置此字段的是否存储而从 _source字段中分离
true/false(默认)coerce:是否开启自动数据类型转换功能,如字符串转整形,浮点转整形
true(默认)/falseanalyzer:指定分词器,默认分词器是 standard analyzer
"analyzer": "ik"boost:字段级别的分数加权,默认值是 1.0
"boost": 1.25data_detection:是否自动识别日期类型
true(默认)/falsefields:对一个字段提供多种索引模式,同一个字段的值,一个分词一个不分词
"fields":{"raw":{"type":"text","index":"not_analyzed"}}
不分词字段统一建议使用 doc_value
{"fielddata":{"format":"disabled"}}
index/type里面,可以存储任意多的文档typeElasticsearch 与传统关系性数据库相比:
| DB | Database | Table | Row | Column |
|---|---|---|---|---|
| ES | Index | Type | Document | Field |
查询所有数据:
POST /user/_doc/_search
{
"query": { "match_all": {} }
}
删除索引:
DELETE /user
查看并搜索数据:
GET /user/_doc/_search?pretty
{
"query": {
"bool": {
"must_not": [{"terms": {"user_id.keyword": ["USER4b862aaa-2df8654a-7eb4bb65e3507f66", "USER14eeeaa5-442771b9-0262e455e4663d1d", "USER484a6734-03a124f0-996c169dd05c1869"]}}],
"should": [
{"match": {"user_id": "昵称"}},
{"match": {"nickname": "昵称"}},
{"match": {"phone": "昵称"}}
]
}
}
}
便于阅读:
[
{"index": {"_id": "1"}, "user": {"user_id": "USER4b862aaa-2df8654a-7eb4bb65e3507f66", "nickname": "昵称 1", "phone": "手机号 1", "description": "签名 1", "avatar_id": "头像 1"}},
{"index": {"_id": "2"}, "user": {"user_id": "USER14eeeaa5-442771b9-0262e455e4663d1d", "nickname": "昵称 2", "phone": "手机号 2", "description": "签名 2", "avatar_id": "头像 2"}},
{"index": {"_id": "3"}, "user": {"user_id": "USER484a6734-03a124f0-996c169dd05c1869", "nickname": "昵称 3", "phone": "手机号 3", "description": "签名 3", "avatar_id": "头像 3"}},
{"index": {"_id": "4"}, "user": {"user_id": "USER186ade83-4460d4a6-8c08068f83127b5d", "nickname": "昵称 4", "phone": "手机号 4", "description": "签名 4", "avatar_id": "头像 4"}},
{"index": {"_id": "5"}, "user": {"user_id": "USER6f19d074-c33891cf-23bf5a8357189a19", "nickname": "昵称 5", "phone": "手机号 5", "description": "签名 5", "avatar_id": "头像 5"}},
{"index": {"_id": "6"}, "user": {"user_id": "USER97605c64-9833ebb7-d045535335a59195", "nickname": "昵称 6", "phone": "手机号 6", "description": "签名 6", "avatar_id": "头像 6"}}
]
插入形式:
POST /user/_doc/_bulk
{
"index": {"_id": "1"}
}
{"user_id": "USER4b862aaa-2df8654a-7eb4bb65e3507f66", "nickname": "昵称 1", "phone": "手机号 1", "description": "签名 1", "avatar_id": "头像 1"}
{
"index": {"_id": "2"}
}
{"user_id": "USER14eeeaa5-442771b9-0262e455e4663d1d", "nickname": "昵称 2", "phone": "手机号 2", "description": "签名 2", "avatar_id": "头像 2"}
{
"index": {"_id": "3"}
}
{"user_id": "USER484a6734-03a124f0-996c169dd05c1869", "nickname": "昵称 3", "phone": "手机号 3", "description": "签名 3", "avatar_id": "头像 3"}
{
"index": {"_id": "4"}
}
{"user_id": "USER186ade83-4460d4a6-8c08068f83127b5d", "nickname": "昵称 4", "phone": "手机号 4", "description": "签名 4", "avatar_id": "头像 4"}
{
"index": {"_id": "5"}
}
{"user_id": "USER6f19d074-c33891cf-23bf5a8357189a19", "nickname": "昵称 5", "phone": "手机号 5", "description": "签名 5", "avatar_id": "头像 5"}
{
"index": {"_id": "6"}
}
{"user_id": "USER97605c64-9833ebb7-d045535335a59195", "nickname": "昵称 6", "phone": "手机号 6", "description": "签名 6", "avatar_id": "头像 6"}
创建索引库:
POST /user/_doc
{
"settings": {
"analysis": {
"analyzer": {
"ik": {
"tokenizer": "ik_max_word"
}
}
}
},
"mappings": {
"dynamic": true,
"properties": {
"nickname": {"type": "text", "analyzer": "ik_max_word"},
"user_id": {"type": "keyword", "analyzer": "standard"},
"phone": {"type": "keyword", "analyzer": "standard"},
"description": {"type": "text", "enabled": false},
"avatar_id": {"type": "keyword", "enabled": false}
}
}
}
安装:
# 克隆代码
git clone https://github.com/seznam/elasticlient
# 切换目录
cd elasticlient
# 更新子模块
git submodule update --init --recursive
# 编译代码
make build && cd build
cmake ..
make
# 安装
make install
前置安装:依赖 MicroHTTPD库
sudo apt-get install libmicrohttpd-dev
/**
* Perform search on nodes until it is successful. Throws exception if all nodes
* has failed to respond.
* \param indexName specification of an Elasticsearch index.
* \param docType specification of an Elasticsearch document type.
* \param body Elasticsearch request body.
* \param routing Elasticsearch routing. If empty, no routing has been used.
*
* \return cpr::Response if any of node responds to request.
* \throws ConnectionException if all hosts in cluster failed to respond.
*/
cpr::Response search(const std::string &indexName,
const std::string &docType,
const std::string &body,
const std::string &routing = std::string());
/**
* Get document with specified id from cluster. Throws exception if all nodes
* has failed to respond.
* \param indexName specification of an Elasticsearch index.
* \param docType specification of an Elasticsearch document type.
* \param id Id of document which should be retrieved.
* \param routing Elasticsearch routing. If empty, no routing has been used.
*
* \return cpr::Response if any of node responds to request.
* \throws ConnectionException if all hosts in cluster failed to respond.
*/
cpr::Response get(const std::string &indexName,
const std::string &docType,
const std::string &id = std::string(),
const std::string &routing = std::string());
/**
* Index new document to cluster. Throws exception if all nodes has failed to respond.
* \param indexName specification of an Elasticsearch index.
* \param docType specification of an Elasticsearch document type.
* \param body Elasticsearch request body.
* \param id Id of document which should be indexed. If empty, id will be generated
* automatically by Elasticsearch cluster.
* \param routing Elasticsearch routing. If empty, no routing has been used.
*
* \return cpr::Response if any of node responds to request.
* \throws ConnectionException if all hosts in cluster failed to respond.
*/
cpr::Response index(const std::string &indexName,
const std::string &docType,
const std::string &id,
const std::string &body,
const std::string &routing = std::string());
/**
* Delete document with specified id from cluster. Throws exception if all nodes
* has failed to respond.
* \param indexName specification of an Elasticsearch index.
* \param docType specification of an Elasticsearch document type.
* \param id Id of document which should be deleted.
* \param routing Elasticsearch routing. If empty, no routing has been used.
*
* \return cpr::Response if any of node responds to request.
* \throws ConnectionException if all hosts in cluster failed to respond.
*/
cpr::Response remove(const std::string &indexName,
const std::string &docType,
const std::string &id,
const std::string &routing = std::string());
http://127.0.0.1:9200/ES 客户端使用注意:
#include <iostream>
#include <elasticlient/client.h>
#include <cpr/cpr.h>
int main() {
// 1.构造 ES 客户端
elasticlient::Client client({"http://127.0.0.1:9200/"});
// 2.发起搜索请求
try {
auto resp = client.search("user", "_doc", "{\"query\": { \"match_all\":{} }}");
std::cout << resp.status_code << std::endl;
std::cout << resp.text << std::endl;
} catch (std::exception &e) {
std::cout << e.what() << std::endl;
return -1;
}
return 0;
}

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online