快速了解GO+ElasticSearch
更多个人笔记见:
(注意点击“继续”,而不是“发现新项目”)
github个人笔记仓库 https://github.com/ZHLOVEYY/IT_note
gitee 个人笔记仓库 https://gitee.com/harryhack/it_note
个人学习,学习过程中还会不断补充~ (后续会更新在github上)
文章目录
- 简单介绍
- 经典例子
- 示范 demo 代码
- 优化后的代码
- 参考:es 返回格式示例:
- 空指针问题
简单介绍
ES 是一个分布式搜索和分析引擎,用于高效全文搜索。
与 Mysql 存储后查询相比,ES支持用户快速搜索“包含某关键词的文章,以及实现“附近动态”或“热门话题”等复杂排序和过滤
经典例子
GO 相关包:go get -u github.com/elastic/go-elasticsearch/v8
docker 快速部署:docker run -d --name elasticsearch -p 9200:9200 -e "discovery.type=single-node" elasticsearch:8.14.0
# 启用现有容器
docker start elasticsearch#如果希望重新部署:
# 首先停止容器(如果它在运行)
docker stop elasticsearch# 然后移除容器
docker rm elasticsearch# 查看容器
docker ps -a | grep elasticsearch
启动后你会发现,访问不行。这是因为 es 设置了密码和安全验证,那么我们在开发环境下可以这么启动:
docker run -d --name elasticsearch \-p 9200:9200 \-e "discovery.type=single-node" \-e "xpack.security.enabled=false" \elasticsearch:8.14.0
记得先用上面的指令暂停之前的容器并移除,重新 docker 启动
示范 demo 代码
package mainimport ("log""strings""github.com/elastic/go-elasticsearch/v8"
)func main() {cfg := elasticsearch.Config{Addresses: []string{"http://localhost:9200"},}es, err := elasticsearch.NewClient(cfg)if err != nil {log.Fatalf("Error creating Elasticsearch client: %v", err)}// 索引一个文档_, err = es.Index("posts", strings.NewReader(`{"title":"Test Post","content":"Hello world"}`))if err != nil {log.Fatalf("Error indexing document: %v", err)}// 搜索res, err := es.Search(es.Search.WithIndex("posts"),es.Search.WithQuery("hello"),)if err != nil {log.Fatalf("Error searching: %v", err)}defer res.Body.Close()log.Println(res.String())
}
发现看到的结果不太能看懂,进行进一步解析:
优化后的代码
package mainimport ("encoding/json""log""strings""github.com/elastic/go-elasticsearch/v8"
)func main() {cfg := elasticsearch.Config{Addresses: []string{"http://localhost:9200"},}es, err := elasticsearch.NewClient(cfg)if err != nil {log.Fatalf("Error creating Elasticsearch client: %v", err)}// 在搜索前刷新索引_, err = es.Indices.Refresh(es.Indices.Refresh.WithIndex("posts"))if err != nil {log.Fatalf("Error refreshing index: %v", err)}// 索引一个文档_, err = es.Index("posts", strings.NewReader(`{"title":"Test Post","content":"Hello world"}`))if err != nil {log.Fatalf("Error indexing document: %v", err)}// 搜索res, err := es.Search(es.Search.WithIndex("posts"),es.Search.WithBody(strings.NewReader(`{"query": {"match": {"content": "hello"}}}`)),)if err != nil {log.Fatalf("Error searching: %v", err)}defer res.Body.Close()// 解析搜索结果 (这个算是一个通用的模板)var r map[string]interface{}if err := json.NewDecoder(res.Body).Decode(&r); err != nil {log.Fatalf("Error parsing the response body: %s", err)}// 现在可以访问解析后的结果hits := r["hits"].(map[string]interface{})["hits"].([]interface{})for _, hit := range hits {source := hit.(map[string]interface{})["_source"]log.Printf("Found document: %v", source)}
}
这样就可以看到很好的输出结果。
不过记得如果不注释,每次执行程序都会新建一个索引的
参考:es 返回格式示例:
{"took": 10, // 查询耗时(毫秒)"timed_out": false, // 是否超时"hits": { // 命中结果"total": { // 总匹配数"value": 2, // 具体数量"relation": "eq" // 计数关系(eq 表示精确值)},"max_score": 1.0, // 最高相关性得分"hits": [ // 文档数组{"_index": "my_index", // 索引名"_id": "1", // 文档ID"_score": 1.0, // 当前文档得分"_source": { // 原始文档数据 这是我们需要的!!"title": "Elasticsearch入门","content": "学习ES基础用法"}}]}
}
空指针问题
下面这个函数在解析 es 结果的时候会报空指针的错误,分析下原因
func SearchPosts(query string) ([]models.Post, error) {var posts []models.Postres, err := esClient.Search(esClient.Search.WithIndex("posts"),esClient.Search.WithQuery(`{"match": {"title": {"query": "`+query+`"}}}`), //查询针对的是文档的 title 字段,使用的是 match 查询,这是一种全文检索查询,用变量 query 的值作为搜索词)if err != nil {return nil, err}defer res.Body.Close()// 解析结果(简化处理,仅提取 hits)var result map[string]interface{}if err := json.NewDecoder(res.Body).Decode(&result); err != nil { //将结果放入 result 中return nil, err}hits := result["hits"].(map[string]interface{})["hits"].([]interface{})for _, hit := range hits {source := hit.(map[string]interface{})["_source"].(map[string]interface{})posts = append(posts, models.Post{Title: source["title"].(string), //结构化输出,放入结构体,然后放入列表中Content: source["content"].(string),})}return posts, nil
}
这个函数存在空指针错误,原因如下:
- 如果 ES 返回的响应中缺少
hits
字段(如查询语法错误或索引不存在),result["hits"].(map[string]interface{})
会触发panic
。 - 即使
hits
存在,若搜索结果为空(hits.hits
为空数组),循环内的hit(map[string]interface{})
虽不会报错,但后续对_source
的访问仍需校验 - 进一步的,如果某文档无
title
或content
字段,source["title"].(string)
会因类型断言失败或字段不存在而崩溃
结合前面的参照 es 的返回格式更好理解
所以可以采用逐层校验的方式:
hits, ok := result["hits"].(map[string]interface{})
if !ok {return nil, fmt.Errorf("invalid hits format in ES response")
}hitList, ok := hits["hits"].([]interface{})
if !ok {return nil, fmt.Errorf("invalid hits.hits format")
}for _, hit := range hitList {hitMap, ok := hit.(map[string]interface{})if !ok {continue // 跳过无效条目}source, ok := hitMap["_source"].(map[string]interface{})if !ok {continue}// 安全获取字段(支持缺省值)title, _ := source["title"].(string) // 若字段不存在,title=""content, _ := source["content"].(string)posts = append(posts, models.Post{Title: title,Content: content,})
}
这就是优化后对于数据的解析
我的博客中还有后续进阶的例子可以查看~
相关文章:
快速了解GO+ElasticSearch
更多个人笔记见: (注意点击“继续”,而不是“发现新项目”) github个人笔记仓库 https://github.com/ZHLOVEYY/IT_note gitee 个人笔记仓库 https://gitee.com/harryhack/it_note 个人学习,学习过程中还会不断补充&…...

定制开发开源AI智能名片驱动下的海报工厂S2B2C商城小程序运营策略——基于社群口碑传播与子市场细分的实证研究
摘要 本文聚焦“定制开发开源AI智能名片S2B2C商城小程序”技术与海报工厂业务的融合实践,探讨其如何通过风格化海报矩阵的精细化开发、AI技术驱动的用户体验升级,以及S2B2C模式下的社群裂变机制,实现“工具功能-社交传播-商业变现”的生态…...

【Unity开发】控制手机移动端的震动
🐾 个人主页 🐾 阿松爱睡觉,横竖醒不来 🏅你可以不屠龙,但不能不磨剑🗡 目录 一、前言二、Unity的Handheld.Vibrate()三、调用Android原生代码四、NiceVibrations插件五、DeviceVibration插件六、控制游戏手…...
JAVA中的注解和泛型
目录 JAVA注解介绍 概念 注解的本质 4种标准元注解 自定义注解 泛型介绍 泛型的定义 JAVA泛型 泛型方法( ) 泛型类( ) 类型通配符 类型擦除 JAVA注解介绍 概念 注解是 JDK 5.0 引入的一种元数据机制,用来对代码进行标注。它不会影…...

Cesium快速入门到精通系列教程二:添加地形与添加自定义地形、相机控制
一、添加地形与添加自定义地形 在 Cesium 1.93 中添加地形可以通过配置terrainProvider实现。Cesium 支持多种地形数据源,包括 Cesium Ion 提供的全球地形、自定义地形服务以及开源地形数据。下面介绍几种常见的添加地形的方法: 使用 Cesium Ion 全球地…...
汽车零配件---ecu开发工厂学习
ecu成品制作工艺流程 一、PCB 设计与制作(打板) 工艺流程步骤 需求分析与电路设计 根据 ECU 功能(如发动机控制、变速箱控制)确定所需芯片(如 MCU、传感器接口芯片)、外围电路(如电源、通信接…...

python学习打卡day43
DAY 43 复习日 作业: kaggle找到一个图像数据集,用cnn网络进行训练并且用grad-cam做可视化 浙大疏锦行 数据集使用猫狗数据集,训练集中包含猫图像4000张、狗图像4005张。测试集包含猫图像1012张,狗图像1013张。以下是数据集的下…...

Microsoft Word使用技巧分享(本科毕业论文版)
小铃铛最近终于完成了毕业答辩后空闲下来了,但是由于学校没有给出准确地参考模板,相信诸位朋友们也在调整排版时感到头疼,接下来小铃铛就自己使用到的一些排版技巧分享给大家。 注:以下某些设置是根据哈尔滨工业大学(威…...

windows安装多个版本composer
一、需求场景 公司存在多个项目,有的项目比较老,需要composer 1.X版本才能使用 新的项目又需要composer 2.X版本才能使用 所以需要同时安装多个版本的composer二、下载多个版本composer #composer官网 https://getcomposer.org/download/三、放到指定目…...

【办公类-22-05】20250601Python模拟点击鼠标上传CSDN12篇
、 背景需求: 每周为了获取流量券,每天上传2篇,获得1500流量券,每周共上传12篇,才能获得3000和500的券。之前我用UIBOT模拟上传12篇。 【办公类-22-04】20240418 UIBOT模拟上传每天两篇,获取流量券,并删除内容_csdn 每日任务流量券-CSDN博客文章浏览阅读863次,点赞18…...

贪心算法应用:边着色问题详解
贪心算法应用:边着色问题详解 贪心算法是一种在每一步选择中都采取当前状态下最优的选择,从而希望导致结果是全局最优的算法策略。边着色问题是图论中的一个经典问题,贪心算法可以有效地解决它。下面我将从基础概念到具体实现,全…...
【蓝桥杯】包子凑数
包子凑数 题目描述 小明几乎每天早晨都会在一家包子铺吃早餐。他发现这家包子铺有 NN 种蒸笼,其中第 ii 种蒸笼恰好能放 AiAi 个包子。每种蒸笼都有非常多笼,可以认为是无限笼。 每当有顾客想买 XX 个包子,卖包子的大叔就会迅速选出若干…...

ck-editor5的研究 (2):对 CKEditor5 进行设计,并封装成一个可用的 vue 组件
前言 在上一篇文章中—— ck-editor5的研究(1):快速把 CKEditor5 集成到 nuxt 中 ,我仅仅是把 ckeditor5 引入到了 nuxt 中,功能还不算通用。 这一篇内容将会对其进行设计,并封装成可复用的 vue 组件&…...

Java-redis实现限时在线秒杀功能
1.使用redisson pom文件添加redisson <!--redisson--><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.23.4</version></dependency> 2.mysql数据库表设…...

simulink mask、sfunction和tlc的联动、接口
这里全部是讲的level2 sfunction(用m语言编写),基于matlab 2020a。 1.mask的参数操作 1)mask通过set_param和get_param这2个函数接口对mask里面定义的Parameters&Dialog的参数的大部分属性进行读写,一般是Value值…...

VMWare安装常见问题
如果之前安装过VMWare软件,只要是 15/16 版本的,可以正常使用的,不用卸载!!! 如果之前安装过,卸载了,一定要保证通过正常的渠道去卸载(通过控制面板卸载软件)…...
set_property LOC约束
##下列指令是用于清除自带GT CELL相关的LOC约束,或者覆盖 ##你需要把IP中自带的GT cell相关的LOC约束清除掉,或者覆盖掉 ##以下命令可以用来覆盖GT_CHANNEL的LOC约束, 在这条命令之后执行你自己的physical constraint: ##GT的channel的相关管脚有两种设计…...

【北邮 操作系统】第十二章 文件系统实现
一、文件的物理结构 1.1 文件块、磁盘块 类似于内存分页,磁盘中的存储单元也会被分为一个个“块/磁盘块/物理块”。很多操作系统中,磁盘块的大小与内存块、页面的大小相同 内存与磁盘之间的数据交换(即读/写操作、磁盘I/0)都是以“块”为单位进行的。即…...

Docker 插件生态:从网络插件到存储插件的扩展能力解析
Docker 容器技术以其轻量、快速、可移植的特性,迅速成为构建和部署现代应用的核心工具。然而,尽管 Docker Engine 自身功能强大,但在面对多样化的生产环境和复杂业务需求时,仅靠核心功能往往无法满足所有场景。 例如,跨主机的容器网络通信、异构存储系统的持久化数据管理…...

WordPress搜索引擎优化的最佳重定向插件:进阶指南
在管理网站时,我们经常需要调整网页地址或修复错误链接。这时,通过重定向不仅能有效解决这些问题,还能显著提升网站在搜索引擎中的排名。对于熟悉基础重定向插件的用户来说,一些功能更强大的工具可以帮助你更全面地管理网站&#…...

org.junit.runners.model.InvalidTestClassError:此类问题的解决
不知道大家是否遇见过以上这种情况,我也是今天被这个错误搞得很烦,后来通过网上查找资料终于找到了问题所在————就是简单的Test注解的错误使用 Test注解的注意情况 :1 权限必须是public 2 不能有参数 3 返回值类型是void 4 本类的其他的…...

用户管理页面(解决toggleRowSelection在dialog用不了的隐患,包含el-table的plus版本的组件)
新增/编辑/删除/分配角色,图片上传在此文章分类下另一个文章 1.重点分配角色: <template><!-- 客户资料 --><div class"pageBox"><elPlusTable :tableData"tableData" :tablePage"tablePage" onSi…...
打卡第35天:GPU训练以及类的Call方法
知识点回归: 1.CPU性能的查看:看架构代际、核心数、线程数 2.GPU性能的查看:看显存、看级别、看架构代际 3.GPU训练的方法:数据和模型移动到GPU device上 4.类的call方法:为什么定义前向传播时可以直接写作self.fc1(x)…...

Linux-GCC、makefile、GDB
GCC gcc -E test.c -o test.i预处理(-o指定文件名) gcc -S test.i -o test.s编译gcc -c test.s -o test.o汇编gcc test.o -o test链接(生成一个可执行程序的软连接) gcc test.c -o test一条指令可以完成以上所有内容 gcc *.c -I(大写的i) include由于在main.c中找不到当前文件…...

[MySQL初阶]MySQL(7) 表的内外连接
标题:[MySQL初阶]MySQL(7)表的内外连接 水墨不写bug 文章目录 一. 内连接 (INNER JOIN)二. 外连接 (OUTER JOIN)关键区别总结 三、 如何选择 在 MySQL 中,连接(JOIN)用于根据两个或多个表之间的相关列组合行。内连接(I…...
Spring Boot中Excel处理完全指南:从基础到高级实践
Excel处理基础知识 1.1 为什么需要在应用中处理Excel文件? 在企业应用开发中,Excel文件处理是一个非常常见的需求,主要用于以下场景: 数据导入:允许用户通过Excel上传批量数据到系统 数据导出:将系统数据…...
Windows下NVM的安装与使用
本文将介绍windows下nvm相关知识。 在不同的项目中可能会使用不同版本的Node.js,例如A项目中需要node>18;B项目中需要node>20。这时候就需要使用NVM切换不同的node版本。进而可以在同一台设备上使用多个node版本。 一、NVM是什么? n…...
Ubuntu挂起和休眠
Ubuntu挂起和休眠 1. 挂起(Suspend)2. 休眠(Hibernate)3. 混合挂起(Hybrid-Sleep)注意事项图形界面操作 在 Ubuntu 系统中,挂起(Suspend)和休眠(Hibernate&am…...

【R语言编程绘图-mlbench】
mlbench库简介 mlbench是一个用于机器学习的R语言扩展包,主要用于提供经典的基准数据集和工具,常用于算法测试、教学演示或研究场景。该库包含多个知名数据集,涵盖分类、回归、聚类等任务。 包含的主要数据集 BostonHousing 波士顿房价数据…...
云服务器部署Gin+gorm 项目 demo
更多个人笔记见: (注意点击“继续”,而不是“发现新项目”) github个人笔记仓库 https://github.com/ZHLOVEYY/IT_note gitee 个人笔记仓库 https://gitee.com/harryhack/it_note 个人学习,学习过程中还会不断补充&…...