惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Fortinet All Blogs
云风的 BLOG
云风的 BLOG
M
MIT News - Artificial intelligence
WordPress大学
WordPress大学
T
Tailwind CSS Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
S
Secure Thoughts
博客园 - 【当耐特】
Know Your Adversary
Know Your Adversary
NISL@THU
NISL@THU
博客园 - 司徒正美
Last Week in AI
Last Week in AI
C
Cybersecurity and Infrastructure Security Agency CISA
P
Privacy & Cybersecurity Law Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
B
Blog
The GitHub Blog
The GitHub Blog
小众软件
小众软件
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Spread Privacy
Spread Privacy
Martin Fowler
Martin Fowler
博客园 - 叶小钗
Security Archives - TechRepublic
Security Archives - TechRepublic
T
Tenable Blog
S
Securelist
博客园 - 三生石上(FineUI控件)
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Microsoft Security Blog
Microsoft Security Blog
Apple Machine Learning Research
Apple Machine Learning Research
罗磊的独立博客
T
Threat Research - Cisco Blogs
Application and Cybersecurity Blog
Application and Cybersecurity Blog
F
Full Disclosure
Cloudbric
Cloudbric
The Cloudflare Blog
Y
Y Combinator Blog
Hugging Face - Blog
Hugging Face - Blog
Microsoft Azure Blog
Microsoft Azure Blog
H
Hacker News: Front Page
腾讯CDC
L
Lohrmann on Cybersecurity
C
CERT Recently Published Vulnerability Notes
V2EX - 技术
V2EX - 技术
GbyAI
GbyAI
TaoSecurity Blog
TaoSecurity Blog
I
Intezer
The Last Watchdog
The Last Watchdog
G
GRAHAM CLULEY
Google Online Security Blog
Google Online Security Blog
T
The Blog of Author Tim Ferriss

博客园 - 柒零壹

Ubuntu 24.04 安装最新版podman@5.6.1 [转贴]在前端如何玩转 Word 文档 一个命令行参数解决open-webui镜像启动失败的问题(huggingface网站访问失败问题) Go Template 常用疑难知识点 从数据库中随机选取数据(基于golang,xorm) golang用pgx查询数据时如何将查询结果方便的放入Map中 go语言如何使用elastic官方客户端go-elasticsearch/v8实现数据批量更新 【转】网络常用颜文字(文字表情) GoCV下实现多图片单窗口内同时显示 解决GoCV/OpenCV不支持中文的问题 golang中xorm自动维护表结构自动导入数据的实现 [golang] gin的中间中调用Abort方法导致的带附件的表单提交时,浏览器报net::ERR_CONNECTION_RESET错误的原因及解决方法 [golang]filepath.Glob的缺陷,不支持多级目录 浏览器中javascript简易实现json数据保存到客户端 最简单搭建前端轻量级项目开发服务 [转]Three.js做一个酷炫的城市展示可视化大屏 [转]css实现不同样式的tooltip对话框小三角 [原]升级项目到Rails7.0.3,使用自己手动方案编译打包css及js资源 puma web server如何监听所有IP地址
go-ElasticSearch TypedClient学习笔记
柒零壹 · 2023-08-04 · via 博客园 - 柒零壹

ElasticSearch

Elasticsearch(ES)是一个基于Lucene构建的开源、分布式、RESTful接口的全文搜索引擎。Elasticsearch还是一个分布式文档数据库,其中每个字段均可被索引,而且每个字段的数据均可被搜索,ES能够横向扩展至数以百计的服务器存储以及处理**PB**级的数据。可以在极短的时间内存储、搜索和分析大量的数据。通常作为具有复杂搜索场景情况下的核心发动机。根据DB-Engines的排名显示,Elasticsearch`是最受欢迎的企业搜索引擎。

go-ealsticsearch

Elasticsearch 的官方 Go 客户端go-elasticsearch是由 Elastic 开发、维护和支持的客户端系列的最新成员之一。 初始版本于 2019 年初发布,并在过去几年中逐渐成熟,获得了重试请求、发现集群节点和各种辅助组件等功能。

随着官方客户端的发布和逐渐成熟,原来社区维护的客户端olivere/elastic已经逐渐不在维护了。

Typed API

Typed API从简单开始,到逐步扩展覆盖更多领域,提升类型安全性和易用性。成为该客户端库的一大特色。

Typed API早在2.19年的V7版本中就出现了,不过一直处于alpha状态,直到8.7版本,才基本可用。我用的是最新的8.90版,看到TypedApi的介绍,就选择入坑选择了。没想到,还真的坑啊,基本的增删改还好,稍微复杂的用法只能去找examples和tests代码,加上自己试验,连文档都没有:(。所以在这里记录一下我用到的TypedAPI。

连接EL

 var err error
 esCfg:=es.Config{
   Addresses: []string{"http://192.168.0.134:9200"},
   Username:  "Username",
   Password:  "Password",
 }
 typedClient, err := es.NewTypedClient(esCfg)
 if err != nil {
   log.Fatal("创建TypedClient失败",err)
 }
 
 

EL中的实体类

 type ElKnowledge struct {
  ID          int       `json:"id"`
  KnowledgeID string    `json:"knowledge_id"`
  Title       string    `json:"title"`
  Author      string    `json:"author"`
  Category    string    `json:"category"`
  Keywords    string    `json:"keywords"`
  Content     string    `json:"content"`
  Images      string    `json:"images"`
  Files       string    `json:"files"`
  DAddAt      time.Time `json:"d_add_at"`
  AddAt       string    `json:"add_at"`
  Comments    string    `json:"comments"`
  Scores      string    `json:"scores"`
 }
 func (me *ElKnowledge) SID() string {
  return me.KnowledgeID
 }
 func (me *ElKnowledge) ToJsonRawMessage() json.RawMessage {
  bf, err := json.Marshal(me)
  if err != nil {
  log.Fatalln("[ElKnowledge.ToJson] fail", err)
  }
  return bf
 }
 func (me *ElKnowledge) ToJson() string {
  return string(me.ToJsonRawMessage())
 }
 

创建索引

 indexName:="myIndex"
 var ElKnowledgeTypedMapping *types.TypeMapping = &types.TypeMapping{
  Properties: map[string]types.Property{
  "id":           types.NewIntegerNumberProperty(),
  "knowledge_id": types.NewKeywordProperty(),
  "title":        types.NewTextProperty(),
  "category":     types.NewTextProperty(),
  "author":       types.NewTextProperty(),
  "keywords":     types.NewTextProperty(),
  "content":      types.NewTextProperty(),
  "add_at":       types.NewKeywordProperty(),
  "images":       types.NewTextProperty(),
  "files":        types.NewTextProperty(),
  "d_add_at":     types.NewDateProperty(),
  "comments":     types.NewTextProperty(),
  "scores":       types.NewTextProperty(),
  },
 }
 

新增

 func  insertKnowledge(doc *ElKnowledge){
  sid:=doc.SID()
  rr,err:=typedClient.Create(indexName,sid).Request(&doc).Do(context.TODO())
  if err!=nil{
  log.Fatal(" Insert new doc fail,",err)
  }
  log.Println(" Insert new doc, result=>",rr.Result.String())
 }
 

按ID查询

 func  GetKnowledge(sid string)(doc *ElKnowledge,ok bool){
  rr,err:=typedClient.Get(indexName,sid).Do(context.TODO())
  if err!=nil{
  log.Println("[GetKnowledge] fail",err)
  return
  }
  if !rr.Found {return }
  doc,err= ElKnowledgeFromJsonRaw(rr.Source_)
  if err!=nil{
  return
  }
  return doc, true
 }
 

修改

 func  upsertKnowledge(doc *ElKnowledge){  
  useUpsert:=true
  sid:=doc.SID()
  js:=doc.ToJson()
  rr,err:=typedClient.Update(indexName,sid).Request(&update.Request{
  Doc: json.RawMessage(js),
  DocAsUpsert: &useUpsert,
  }).Do(context.TODO())
  if err!=nil{
  log.Println("upsert doc fail,",err)
  panic(err)
  }
  log.Println("upserted success, by way=>",rr.Result.String())
 }

删除

 func deleteKnowledge(doc *ElKnowledge){
  sid:=doc.SID()
  rr,err:=typedClient.Delete(indexName,sid).Do(context.TODO())
  if err!=nil{
  log.Fatal("Delete doc fail",err)
  }
  log.Println("Deleted, ",rr.Result.String())
 }

查询

 func Search(c *gin.Context) {
  words:=c.Query("words")
  sfrom:=c.Query("from")
  ssize:=c.Query("size")
  from,_:=strconv.Atoi(sfrom)
  size,_:=strconv.Atoi(ssize)
  res,err:=typedClient.Search().Index("yhkb").Request(&search.Request{
  Query: &types.Query{
  Match: map[string]types.MatchQuery{
  "all_content": { Query: words, Operator: &operator.And},
  },
  },
  Sort: []types.SortCombinations{
  types.SortOptions{
  SortOptions: map[string]types.FieldSort{
  "add_at":{Order: &sortorder.Desc,},
  },
  },
  },
  From: &from,
  Size: &size,
  }).Do(context.Background())
 
  if err != nil {
  msg:=""
  if err,ok:=err.(types.ElasticsearchError);ok{
  b,_:=json.Marshal(err)
  msg=string(b)
  }
  err=utils.WrapErrorWith(err,"查询失败"+msg)
  slog.Error("查询失败","error",err)
  helper.ResponseJsonError(c, err)
  return
  }
  helper.ResponseJsonData(c,res)
 
 }