6.聊天室環境安裝 - Ubuntu22.04 - elasticsearch(es)的安裝和使用

目錄

  • 介紹
  • 安裝
  • 安裝kibana
  • 安裝ES客戶端
  • 使用

介紹

Elasticsearch, 簡稱 ES,它是個開源分布式搜索引擎,它的特點有:分布式,零配置,自動發現,索引自動分片,索引副本機制,restful 風格接口,多數據源,自動搜索負載等。它可以近乎實時的存儲、檢索數據;本身擴展性很好,可以擴展到上百臺服務器,處理 PB 級別的數據。es 也使用 Java 開發并使用 Lucene 作為其核心來實現所有索引和搜索的功能,但是它的目的是通過簡單的 RESTful API 來隱藏 Lucene 的復雜性,從而讓全文搜索變得簡單。
Elasticsearch 是面向文檔(document oriented)的,這意味著它可以存儲整個對象或文檔(document)。然而它不僅僅是存儲,還會索引(index)每個文檔的內容使之可以被搜索。在 Elasticsearch 中,你可以對文檔(而非成行成列的數據)進行索引、搜索、排序、過濾。

安裝

1.添加倉庫密鑰
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
2.添加鏡像源倉庫
echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elasticsearch.list
3.更新軟件包列表
sudo apt update
4.安裝es
sudo apt-get install elasticsearch=7.17.21
5.安裝ik分詞器插件
sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install https://get.infini.cloud/elasticsearch/analysis-ik/7.17.21
6.啟動es
sudo systemctl start elasticsearch
6.5如果啟動es失敗
調整 ES 虛擬內存,虛擬內存默認最大映射數為 65530,無法滿足 ES 系統要求,需要調整為 262144 以上
sysctl -w vm.max_map_count=262144
增加虛擬機內存配置
vim /etc/elasticsearch/jvm.options
新增如下內容:
-Xms512m
-Xmx512m
在這里插入圖片描述

設置完后重啟ubuntu
7.查看es服務的狀態
sudo systemctl status elasticsearch.service
在這里插入圖片描述
8.驗證es是否安裝成功
curl -X GET "http://localhost:9200/"
在這里插入圖片描述
9.設置能夠外部訪問: 如果新配置完成默認只能在本機進行訪問
vim /etc/elasticsearch/elasticsearch.yml
新增配置

network.host: 0.0.0.0
http.port: 9200
cluster.initial_master_nodes: ["node-1"]

在這里插入圖片描述
重啟后sudo systemctl restart elasticsearch.service
瀏覽器訪問http://自己的IP:9200/
在這里插入圖片描述

安裝kibana

kibana可以支持通過網頁對ES進行訪問(增刪查改), 這可以讓我們的測試更加直觀一些
1.安裝kibana
sudo apt install kibana
2.配置kibana
sudo vim /etc/kibana/kibana.yml
在7行修改為server.host: "0.0.0.0"
在這里插入圖片描述

在32行修改為elasticsearch.hosts: ["http://0.0.0.0:9200"]
在這里插入圖片描述
3.啟動kibana服務
sudo systemctl start kibana
4.驗證安裝
sudo systemctl status kibana
5.訪問kibana
在瀏覽器訪問kibana, http://你的ip:5601
在這里插入圖片描述

安裝ES客戶端

1.克隆代碼
git clone https://github.com/seznam/elasticlient
注意: 這里不能從github下載源碼然后拖拽進來, 因為內部有git子模塊, 需要去更新子模塊之后, 才能去編譯
如果無法始終clone不下來, 也有對應的解決方案:https://blog.csdn.net/eyuyanniniu/article/details/145807381
2.切換目錄
cd elasticlient
3.安裝 MicroHTTPD 庫
sudo apt-get install libmicrohttpd-dev
4.更新子模塊
git submodule update --init --recursive
5.編譯安裝代碼
mkdir build
cd build
cmake ..
make
make install

6.配置環境變量
因為我們的庫默認安裝路徑是/usr/local/lib, 編譯器可能找不到這個庫目錄的位置
所以我們需要配置(這些文件最好都進行配置):
全局設置: /etc/profile 當前用戶設置: .bash_profil或.bashrc
在文件末尾加上 export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

使用

封裝icsearch.hpp文件

#include <elasticlient/client.h>
#include <cpr/cpr.h>
#include <json/json.h>
#include <iostream>
#include <memory>
#include "logger.hpp"//ES的二次封裝, 原因: 為了簡化ES的使用操作, 我們可以看到, 請求的時候, 正文很長, 我們希望只設置我們關心的參數即可, 而且能自動的構造完成
//封裝四個操作: 索引創建, 數據新增, 數據查詢, 數據刪除namespace wufan_im{
bool UnSerialize(const std::string& src, Json::Value& val)
{// 同樣的Read類, 需要先構造出工廠類Json::CharReaderBuilder crb;std::unique_ptr<Json::CharReader> cr(crb.newCharReader());std::string err;bool ret = cr->parse(src.c_str(), src.c_str() + src.size(), &val, &err);if (ret == false) {std::cout << "json反序列化失敗: " << err << std::endl;return false;}return true;
}bool Serialize(const Json::Value& val, std::string& dst)
{// Writer(StreamWriter)類, 這個類就是用來序列化的, 但是這個類不能直接構造, 因為使用了工廠模式// 先定義Json::SreamWriter 工廠類 Json::StreamWriterBuilderJson::StreamWriterBuilder swb;  //構造出工廠類std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());// 通過Json::StreamWriter中的write接口進行序列化std::stringstream ss;int ret = sw->write(val, &ss);  //將其序列化到字符流里面if (ret != 0) {std::cout << "Json反序列化失敗!\n";return false;}dst = ss.str();return true;
}// 索引創建:
// 傳兩個參數, 索引名稱 和 索引類型 就可以創建出索引
// 能夠添加字段, 并設置字段類型, 設置分詞器類型, 是否構造索引
class ESIndex{public:ESIndex(std::shared_ptr<elasticlient::Client>& client, const std::string& name, const std::string& type = "_doc"):_name(name), _type(type), _client(client){Json::Value analysis;   //可以把Value當做Json里的{ }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;}// 創建索引, 就相當于在設置表結構 - ai說的// 添加字段, 就相當于設置表的字段屬性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_ptr<elasticlient::Client> _client;
};// 數據新增
class ESInsert{public:ESInsert(std::shared_ptr<elasticlient::Client>& client, const std::string& name,const std::string& type = "_doc"):_name(name), _type(type), _client(client){}ESInsert& append(const std::string& key, const std::string& val){_item[key] = val;return *this;}// 插入到哪個id里面 -  這個ID就相當于是每一次插入時數據的唯一標識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_ptr<elasticlient::Client> _client;
};// 數據刪除
class ESRemove{public:ESRemove(std::shared_ptr<elasticlient::Client>& client, const std::string& name, const std::string& type):_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_ptr<elasticlient::Client> _client;
};//數據查詢
class ESSearch{public: //用戶還會設置過濾條件,以及應該包含的字段ESSearch(std::shared_ptr<elasticlient::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::vector<std::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;}Json::Value search() {Json::Value cond;if (_must_not.empty() == false) cond["must_not"] = _must_not;if (_should.empty() == false) cond["should"] = _should;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;    //必須包含的, 多選一即可std::shared_ptr<elasticlient::Client> _client;
};
}

main.cc文件

#include "../../common/icsearch.hpp"
#include <gflags/gflags.h>DEFINE_bool(run_mode, false, "程序的運行模式, false-調試; true-發布;");
DEFINE_string(log_file, "", "發布模式下, 用于指定日志的輸出文件");
DEFINE_int32(log_level, 0, "發布模式下, 用于指定日志輸出等級");int main(int argc, char* argv[])
{google::ParseCommandLineFlags(&argc, &argv, true);wufan_im::init_logger(FLAGS_run_mode, FLAGS_log_file, FLAGS_log_level);std::shared_ptr<elasticlient::Client> client(new elasticlient::Client({"http://127.0.0.1:9200/"}));bool ret = wufan_im::ESIndex(client, "test_user")// 創建索引, 就相當于在設置表結構 - ai說的// 添加字段, 就相當于設置表的字段屬性.append("nickname").append("phone", "keyword", "standard", true) //手機號是不能進行分詞的, 是一個關鍵字, 分詞器用標準分詞器, 需要構造索引.create();if (ret == false) {LOG_INFO("索引創建失敗!");return -1;}LOG_INFO("索引創建成功");// 新增數據ret = wufan_im::ESInsert(client, "test_user").append("nickname", "張三").append("phone", "155666777").insert("00001");   // 這個ID就相當于是每一次插入時數據的唯一標識if (ret == false) {LOG_ERROR("數據插入失敗!");return -1;}// 數據的修改ret = wufan_im::ESInsert(client, "test_user").append("nickname", "張三").append("phone", "1334444555").insert("00001");if (ret == false) {LOG_ERROR("數據更新失敗!");return -1;}LOG_INFO("數據新增成功");Json::Value user = wufan_im::ESSearch(client, "test_user").append_should_match("phone.keyword", "1334444555")     //檢索的時候, 告訴ES, 這個關鍵詞不要進行分詞// .append_must_not_terms("nickname.keyword", {"張三"}).search();if (user.empty() || user.isArray() == false) {LOG_ERROR("結果為空, 或者結果不是數組類型");return -1;}LOG_INFO("數據檢索成功");int sz = user.size();LOG_DEBUG("檢索結果條目數量: {}", sz);for (int i = 0; i < sz; ++i) {LOG_INFO("nickname: {}", user[i]["_source"]["nickname"].asString());}ret = wufan_im::ESRemove(client, "test_user", "_doc").remove("00001");if (ret == false) {LOG_ERROR("刪除數據失敗");return -1;}LOG_INFO("數據刪除成功");return 0;
}

運行程序:
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/71867.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/71867.shtml
英文地址,請注明出處:http://en.pswp.cn/web/71867.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SSL VXN

SSL VPN是采用SSL&#xff08;Security Socket Layer&#xff09;/TLS&#xff08;Transport Layer Security&#xff09;協議來實現遠程接入的一種輕量級VPN技術,其基于B/S架構&#xff0c;免于安裝客戶端&#xff0c;相較與IPSEC有更高的靈活度和管理性&#xff0c;當隧道建立…

【Qt】成員函數指針

一、成員函數指針的本質 與普通函數指針的區別&#xff1a; // 普通函數指針 void (*funcPtr)() &普通函數;// 成員函數指針 void (MyClass::*memberFuncPtr)() &MyClass::成員函數;? 綁定對象&#xff1a;成員函數指針必須與類的實例對象結合使用 ? 隱含 this 指…

通義萬相2.1開源版本地化部署攻略,生成視頻再填利器

2025 年 2 月 25 日晚上 11&#xff1a;00 通義萬相 2.1 開源發布&#xff0c;前兩周太忙沒空搞它&#xff0c;這個周末&#xff0c;也來本地化部署一個&#xff0c;體驗生成效果如何&#xff0c;總的來說&#xff0c;它在國內文生視頻、圖生視頻的行列處于領先位置&#xff0c…

Linux——system V共享內存

共享內存區是最快的IPC(進程內通信)形式&#xff0c;不再通過執行進入內核的系統調用來傳遞彼此的數據 1.共享內存的原理 IPC通信的本質是讓不同的進程先看到同一份資源&#xff0c;然后再進行通信&#xff0c;所以想要通過共享內存進行通信&#xff0c;那么第一步一定是讓兩個…

01 SQl注入基礎步驟(數字、字符、布爾盲注、報錯)

目錄 1、SQL注入漏洞的概要 2、SQL注入的常規思路 3、數字型注入 4、字符型注入 5、布爾盲注 6、報錯注入 1、SQL注入漏洞的概要 原理&#xff1a;通過用戶輸入的數據未嚴格過濾&#xff0c;將惡意SQL語句拼接到原始查詢中&#xff0c;從而操控數據庫執行非預期操作。 …

leetcode-sql數據庫面試題沖刺(高頻SQL五十題)

題目&#xff1a; 620.有趣的電影 表&#xff1a;cinema ------------------------ | Column Name | Type | ------------------------ | id | int | | movie | varchar | | description | varchar | | rating | float | ------------------------ id 是該表的主鍵(具有唯一值…

7.2 奇異值分解的基與矩陣

一、奇異值分解 奇異值分解&#xff08;SVD&#xff09;是線性代數的高光時刻。 A A A 是一個 m n m\times n mn 的矩陣&#xff0c;可以是方陣或者長方形矩陣&#xff0c;秩為 r r r。我們要對角化 A A A&#xff0c;但并不是把它化成 X ? 1 A X X^{-1}A X X?1AX 的形…

在本地部署DeepSeek等大模型時,需警惕的潛在安全風險

在本地部署DeepSeek等大模型時&#xff0c;盡管數據存儲在本地環境&#xff08;而非云端&#xff09;&#xff0c;但仍需警惕以下潛在安全風險&#xff1a; 1. 模型與數據存儲風險 未加密的存儲介質&#xff1a;若訓練數據、模型權重或日志以明文形式存儲&#xff0c;可能被物…

【javaEE】多線程(進階)

1.????前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 親愛的朋友們&#x1f44b;&#x1f44b;&#xff0c;這里是E綿綿呀????。 如果你喜歡這篇文章&#xff0c;請別吝嗇你的點贊????和收藏&#x1f4d6;&#x1f4d6;。如果你對我的…

dify中使用NL2SQL

在 Dify 工作流中融入 NL2SQL&#xff08;自然語言轉 SQL&#xff09;之能力&#xff0c;可依循如下步驟達成&#xff0c;借由 Dify 的模塊化設計以及模型編排之功能&#xff0c;優化數據庫查詢之智能化交互&#xff1a; 一、環境準備與 Dify 部署 安裝 Docker 與 Dify 務須確…

使用Everything搜索指定文件夾中的內容

直接路徑搜索法 在 Everything 的搜索框中輸入文件夾路徑加空格&#xff0c;再輸入要搜索的內容或文件名。如要在 D 盤的 “文檔” 文件夾中搜索名為 “報告.docx” 的文件&#xff0c;可輸入 “D:\ 文檔 報告.docx”235。 高級搜索法 打開 Everything 軟件&#xff0c;點擊菜…

Java在小米SU7 Ultra汽車中的技術賦能

目錄 一、智能駕駛“大腦”與實時數據 場景一&#xff1a;海量數據的分布式計算 場景二&#xff1a;實時決策的毫秒級響應 場景三&#xff1a;彈性擴展與容錯機制 技術隱喻&#xff1a; 二、車載信息系統&#xff08;IVI&#xff09;的交互 場景一&#xff1a;Android Automo…

Vue開發中計算屬性與方法調用之間的區別與聯系

文章目錄 一 概述二 核心區別三 聯系四 使用原則 一 概述 在 Vue 中&#xff0c;計算屬性&#xff08;computed&#xff09; 和 方法&#xff08;methods&#xff09; 都可以用于處理數據邏輯&#xff0c;但它們的核心區別在于 緩存機制 和 觸發方式 。 計算屬性示例&#xf…

【Unity】 HTFramework框架(六十一)Project窗口文件夾鎖定器

更新日期&#xff1a;2025年3月7日。 Github源碼&#xff1a;[點我獲取源碼] Gitee源碼&#xff1a;[點我獲取源碼] 索引 Project窗口文件夾鎖定器框架文件夾鎖定自定義文件夾鎖定限制條件 Project窗口文件夾鎖定器 在Project窗口中&#xff0c;文件夾鎖定器能夠為任何文件夾加…

C語言:6.20字符型數據練習題

編寫程序,輸人一行數字字符(用回車結束),每個數字字符 的前后都有空格。 把這一行中的數字轉換成一個整數。 例如,若輸入(<CR>代表 Enter鍵):2 4 8 3<CR>則輸出 整數:2483。 #include <stdio.h>int main() {char ch;int number 0;printf("請輸入一行…

【軟件工程】一篇入門UML建模圖(狀態圖、活動圖、構件圖、部署圖)

&#x1f308; 個人主頁&#xff1a;十二月的貓-CSDN博客 &#x1f525; 系列專欄&#xff1a; &#x1f3c0;軟件開發必練內功_十二月的貓的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻擋不了春天的腳步&#xff0c;十二點的黑夜遮蔽不住黎明的曙光 目錄 1. 前…

【C語言】數組篇

目錄 引言一維數組數組的定義數組的初始化完全初始化部分初始化省略數組長度 數組元素的訪問 多維數組二維數組的定義二維數組的初始化完全初始化部分初始化省略第一維長度 二維數組元素的訪問 遍歷數組元素遍歷一維數組遍歷二維數組 數組作為函數參數一維數組作為函數參數二維…

OpenCV視頻解碼性能優化十連擊(實測幀率提升300%)

解密工業級視頻處理優化方案&#xff01;從硬件加速到多線程榨干CPU/GPU性能&#xff0c;附RTSP流調優參數與內存泄漏排查技巧。 &#x1f527; 優化前準備 環境檢測腳本 import cv2# 驗證硬件加速支持 print("CUDA支持:", cv2.cuda.getCudaEnabledDeviceCount() &…

基于編譯器特性淺析C++程序性能優化

最近在惡補計算機基礎知識&#xff0c;學到CSAPP第五章的內容&#xff0c;在這里總結并且展開一下C程序性能優化相關的內容。 衡量程序性能的方式 一般而言&#xff0c;程序的性能可以用CPE&#xff08;Cycles Per Element&#xff09;來衡量&#xff0c;其指的是處理每個元素…

transformer模型介紹——大語言模型 LLMBook 學習(二)

1. transformer模型 1.1 注意力機制 **注意力機制&#xff08;Attention Mechanism&#xff09;**在人工智能中的應用&#xff0c;實際上是對人類認知系統中的注意力機制的一種模擬。它主要模仿了人類在處理信息時的選擇性注意&#xff08;Selective Attention&#xff09;&a…