Elasticsearch:运用 Go 语言实现 Elasticsearch 搜索
在今天的文章中,我将介绍如何使用 Go 语言来对 Elasticsearch 进行搜索。首先,我假设你已经对 Elastic Stack 有一定的了解。Elasticsearch 获得了极大的欢迎。 在关系数据库中搜索始终会遇到有关可伸缩性和性能的问题。Elasticsearch 是 NoSQL 数据库,在解决这些问题方面非常成功。 它提供了出色的可拓展性和性能,而最突出的功能之一就是相关性分析,它使搜索结果具有很大的灵活性。
Elastic Stack
安装 Elasticsearch 及 Kibana
如果你还没有安装好自己的 Elasticsearch 及 Kibana 的话,那么请参阅我之前的文章:
如何在 Linux,MacOS 及 Windows 上进行安装 Elasticsearch
如何在 Linux,MacOS 及 Windows上安装 Elastic 栈中的 Kibana
一旦完成好 Elasticsearch 及 Kibana 的安装,我们可以在浏览器中输入地址 http://localhost:9200 来进行访问:
我们也可以直接访问 Kibana:
创建你的第一个索引 (index)
在 Elasticsearch中,索引类似于数据库。 以前,elasticsearch 中有一个叫做 type 的表。 但是由于类型已在当前版本中删除,因此现在只有索引。
现在感到困惑吗? 不用了 简而言之,只需考虑只需要索引,然后再将数据插入 Elasticsearch 即可。
现在,我们将通过下面的查询创建一个名为 students 的索引。
PUT students
上面的命令的响应为:
{"acknowledged" : true,"shards_acknowledged" : true,"index" : "students"
}
它已经为我们创建了一个名为 students 的索引。在接下的步骤中,我们将想这个索引里写入一些数据,也就是一些文档。
写入文档到索引中
首先,我们现在要做的是用文档填充我们的 Elasticsearch 索引。 如果你不熟悉该定义,请知道它与数据库中的行非常相似。我们使用如下的命令来把数据导入到 Elasticsearch 中:
POST students/_doc
{"name": "Alice","age": 17,"average_score": 85
}
上面的命令的响应为:
{"_index" : "students","_type" : "_doc","_id" : "cMpCSnUBzapZdaLVYfwW","_version" : 1,"result" : "created","_shards" : {"total" : 2,"successful" : 1,"failed" : 0},"_seq_no" : 0,"_primary_term" : 1
}
你的 Elasticsearch 现在应该有一个文档。 我们将需要在索引 students 中插入更多数据。 当然,我们不会一个接一个地插入我们的学生数据-这很麻烦!
Elasticsearch 特别准备了一个 bulk API,以便一次发送多个请求。 让我们用它一次插入多个数据。
POST students/_bulk
{ "index":{ } }
{ "name":"john doe","age":18, "average_score":77.7 }
{ "index":{} }
{ "name":"bob","age":16, "average_score":65.5 }
{ "index":{} }
{ "name":"mary doe","age":18, "average_score":97.7 }
{ "index":{} }
{ "name":"eve","age":15, "average_score":98.9 }
我们可以通过如下的命令来检查已经输入的 5 个文档:
GET students/_count
搜索索引文档
我们终于在 Elasticsearch 中填充了更多学生的数据。 现在,让我们来做一下 Elasticsearch 众所周知的事情:我们将尝试在 Elasticsearch 中搜索刚刚插入的数据。
Elasticsearch 支持多种类型的搜索机制,但在此示例中,我们将使用简单的匹配查询。
让我们通过点击以下 API 开始搜索:
GET students/_search
{"query": {"match": {"name": "doe"}}
}
上面的命令显示:
{"took" : 0,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 2,"relation" : "eq"},"max_score" : 0.74487394,"hits" : [{"_index" : "students","_type" : "_doc","_id" : "hstFSnUBzapZdaLVQQCN","_score" : 0.74487394,"_source" : {"name" : "john doe","age" : 18,"average_score" : 77.7}},{"_index" : "students","_type" : "_doc","_id" : "iMtFSnUBzapZdaLVQQCN","_score" : 0.74487394,"_source" : {"name" : "mary doe","age" : 18,"average_score" : 97.7}}]}
}
上面将返回你的查询以及与你的相应查询匹配的学生数据。 现在,恭喜你你已经正式成为一名搜索工程师!
让我们使用 Go
如果你已经达到这一部分,那么你应该已经掌握了使用 Elasticsearch 的最低限度的概念。 现在,我们将在 Go 中实现 Elasticsearch。实施 Elasticsearch 的一种非常原始的方法是,你可以继续将 HTTP 请求发送到你的 Elasticsearch IP 中。 但是我们不会那样做。
我发现这个非常有用的库对于在 Go 中实现 Elasticsearch 很有帮助。 在继续执行 Go 模块之前,应先安装该库。我们可以使用如下的命令来进行安装:
go get github.com/olivere/elastic
创建你自己的 struct
首先,你肯定需要为模型制作一个结构。 在此示例中,我们将使用与先前示例相同的建模,在本例中为 Student 结构。
package maintype Student struct {Name string `json:"name"`Age int64 `json:"age"`AverageScore float64 `json:"average_score"`
}
创建客户端连接
现在,让我们创建一个函数,该函数将允许我们初始化 ES Client 连接。
如果你在本地主机外部有一个正在运行的 Elasticsearch 实例,则只需更改 SetURL 中的部分即可。
func GetESClient() (*elastic.Client, error) {client, err := elastic.NewClient(elastic.SetURL("http://localhost:9200"),elastic.SetSniff(false),elastic.SetHealthcheck(false))fmt.Println("ES initialized...")return client, err}
数据插入
之后,我们要做的第一件事就是尝试通过 Go 将数据插入到 Elasticsearch 中。 我们将制作一个 Student 模型,并将其插入到我们的 Elasticsearch 客户端中。
insert.go
package mainimport ("context""encoding/json""fmt""github.com/olivere/elastic"
)type Student struct {Name string `json:"name"`Age int64 `json:"age"`AverageScore float64 `json:"average_score"`
}func GetESClient() (*elastic.Client, error) {client, err := elastic.NewClient(elastic.SetURL("http://localhost:9200"),elastic.SetSniff(false),elastic.SetHealthcheck(false))fmt.Println("ES initialized...")return client, err}func main() {ctx := context.Background()esclient, err := GetESClient()if err != nil {fmt.Println("Error initializing : ", err)panic("Client fail ")}//creating student objectnewStudent := Student{Name: "Gopher doe",Age: 10,AverageScore: 99.9,}dataJSON, err := json.Marshal(newStudent)js := string(dataJSON)_, err = esclient.Index().Index("students").BodyJson(js).Do(ctx)if err != nil {panic(err)}fmt.Println("[Elastic][InsertProduct]Insertion Successful")}
我们可以使用它如下的命令来进行运行:
go run insert.go
上面的应用显示:
$ go run insert.go
ES initialized...
[Elastic][InsertProduct]Insertion Successful
我们可以通过 Kibana 来验证一下新的文档是否已经被成功地写入:
GET students/_search
{"query": {"match": {"name": "Gopher doe"}}
}
上面显示我们的文档已经被成功地写入到 Elasticsearch 之中了。
查询数据
最后,我们可以进行一些搜索。 下面的代码可能看起来有些复杂。 但是请放心,在你仔细地进行操作之后,它对你会更有意义。 在下面的示例中,我将使用基本的匹配查询。
search.go
package mainimport ("context""encoding/json""fmt""github.com/olivere/elastic"
)type Student struct {Name string `json:"name"`Age int64 `json:"age"`AverageScore float64 `json:"average_score"`
}func GetESClient() (*elastic.Client, error) {client, err := elastic.NewClient(elastic.SetURL("http://localhost:9200"),elastic.SetSniff(false),elastic.SetHealthcheck(false))fmt.Println("ES initialized...")return client, err}func main() {ctx := context.Background()esclient, err := GetESClient()if err != nil {fmt.Println("Error initializing : ", err)panic("Client fail ")}var students []StudentsearchSource := elastic.NewSearchSource()searchSource.Query(elastic.NewMatchQuery("name", "Doe"))/* this block will basically print out the es query */queryStr, err1 := searchSource.Source()queryJs, err2 := json.Marshal(queryStr)if err1 != nil || err2 != nil {fmt.Println("[esclient][GetResponse]err during query marshal=", err1, err2)}fmt.Println("[esclient]Final ESQuery=\n", string(queryJs))/* until this block */searchService := esclient.Search().Index("students").SearchSource(searchSource)searchResult, err := searchService.Do(ctx)if err != nil {fmt.Println("[ProductsES][GetPIds]Error=", err)return}for _, hit := range searchResult.Hits.Hits {var student Studenterr := json.Unmarshal(hit.Source, &student)if err != nil {fmt.Println("[Getting Students][Unmarshal] Err=", err)}students = append(students, student)}if err != nil {fmt.Println("Fetching student fail: ", err)} else {for _, s := range students {fmt.Printf("Student found Name: %s, Age: %d, Score: %f \n", s.Name, s.Age, s.AverageScore)}}}
我们使用如下的命令来运行:
go run search.go
查询应像这样打印出来:
ES initialized...
[esclient]Final ESQuery={"query":{"match":{"name":{"query":"Doe"}}}}
是的,该查询就是将要发布到 Elasticsearch 中的内容。如果从一开始就遵循我的示例,则查询结果也应如下所示:
Student found Name: john doe, Age: 18, Score: 77.700000
Student found Name: mary doe, Age: 18, Score: 97.700000
Student found Name: Gopher doe, Age: 10, Score: 99.900000
Hooray! 我们终于完成了第一个使用 Golang 把数据导入到 Elasticsearch 并进行搜索的过程。这个过程非常简单!
如果你想了解更多关于 Elasticsearch 的知识以及其它更为复杂的 DSL 查询,请阅读我的另外一篇文章 “Elastic:菜鸟上手指南”。
Elasticsearch:运用 Go 语言实现 Elasticsearch 搜索相关推荐
- ElasticSearch 2 (21) - 语言处理系列之单词识别
ElasticSearch 2 (21) - 语言处理系列之单词识别 摘要 一个英语单词相对容易识别:因为英语单词是被空格或(某些)标点符号隔开的.但在英语中也有反例:you're 这个词是一个单词还 ...
- ElasticSearch 2 (26) - 语言处理系列之打字或拼写错误
ElasticSearch 2 (26) - 语言处理系列之打字或拼写错误 摘要 我们喜欢在对结构化数据(如:日期和价格)做查询时,结果只返回那些能精确匹配的文档.但是,好的全文搜索不应该有这样的限制 ...
- ElasticSearch 2 (20) - 语言处理系列之如何开始
ElasticSearch 2 (20) - 语言处理系列之如何开始 摘要 Elasticsearch 配备了一组语言分析器,为世界上大多数常见的语言提供良好的现成基础支持. 阿拉伯语.亚美尼亚语,巴 ...
- ElasticSearch 2 (25) - 语言处理系列之同义词
ElasticSearch 2 (25) - 语言处理系列之同义词 摘要 词干提取有助于通过简化屈折词到它们词根的形式来扩展搜索的范围,而同义词是通过关联概念和想法来扩展搜索范围的.或许没有文档能与查 ...
- Elasticsearch(十)【NEST高级客户端--搜索查询】
搜索 Search API允许您执行搜索查询并获取与查询匹配的搜索匹配. Elasticsearch的搜索功能可能是您使用它的原因之一,NEST公开了所有可用的不同类型的搜索,以及一些聪明的使用Ela ...
- 编程随笔-ElasticSearch知识导图(4):搜索
1. 原理 全文搜索是ES的核心功能.ES中的数据按数据特性可分为两类:确切值及全文文本.ES中如keyword,date这些类型的值都可视为确切值.而text类型的值则视为全文文本数据. 为 ...
- Elasticsearch初步学习(仿京东搜索、爬虫)
个人博客欢迎访问 微信搜索程序dunk,关注公众号,获取项目.博客源码 我们面前无所不有,我们面前一无所有 --查尔斯·狄更斯 序号 内容 1 Java基础面试题 2 JVM面试题 3 Java并发编 ...
- 【Elasticsearch】使用Elasticsearch中的copy_to来提高搜索效率
1.概述 转载:使用Elasticsearch中的copy_to来提高搜索效率 在今天的这个教程中,我们来着重讲解一下如何使用Elasticsearch中的copy来提高搜索的效率.比如在我们的搜索中 ...
- 【Elasticsearch】改进布尔查询的搜索相关性
1.概述 翻译:Improving search relevance with boolean queries 有人翻译:Elasticsearch:使用布尔查询提高搜索的相关性 当你在Elastic ...
- 【Elasticsearch】使用Elasticsearch 7.8 快速搭建食谱搜索系统
1.概述 本文参考文章:使用Elasticsearch快速搭建食谱搜索系统 并且对里面的不适合7.8版本的命令进行纠正处理. 简介: 搜索是一个网站的基础功能,一个好的搜索系统可以直接促进页面访问量的 ...
最新文章
- 图灵喜获Stevens名著《TCP/IP Illustrated》影印版权
- 正确的VC2008运行库发行方法
- 力扣(LeetCode)258. 各位相加
- 基于matlab的回波,基于MATLAB回波信号产生与消除.doc
- 前端学习(2990):vue+element今日头条管理--模块介绍
- 多学一招总没错吧?MP通用枚举轻松实现存储显示相分离
- php在类方法里面检测错误,是否有任何PHP静态分析器可以检测不存在的类方法调用?...
- VC遍历窗口上的控件
- uber大数据_Uber创建了深度神经网络以为其他深度神经网络生成训练数据
- wap游戏的一些理解
- jenkins集成sonar问题记录
- 最常用英语单词2000个
- 随机矩阵stochastic matrix和双随机矩阵 doubly stochastic matrix 和bistochastic matrix
- 如何设置input只能输入数字
- python 读写文件 把爬取的图片信息写入文件
- 如何在服务器替换apk文件,如何修改apk文件的服务器地址
- Spring中的 @Lazy注解简析
- 关于使用Navicat,Mysql Workbench,PowerDesigner根据mysql数据库生成ER(实体联系图)的解决方案的总结
- 《圈外课程学习记录》3.2 数据化强力说服
- STM32学习-keil 调试问题1:单步可以执行 全速运行不可以