ElasticSearch的HTTP操作 和Go客户端

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 【2月更文挑战第13天】ElasticSearch的HTTP操作 和Go客户端操作

ElasticSearch是通过暴露HTTP接口来达到操作数据的目的。

字段类型

  1. Text:用于全文检索,例如博客内容、新闻内容、产品描述等。字段内容会被分析,并且在生成倒排索引之前,字符串会被分词器分成一个个词项。Text 类型的字段不用于排序,并且很少用于聚合。这种字段也被称为 analyzed 字段。
  2. Keyword:适用于结构化的字段,例如标签、电子邮件地址、手机号码等。这种类型的字段可以用作过滤、排序、聚合等。这种字段也称之为 not-analyzed 字段。
  3. Binary:用于存储编码为 Base64 的字符串或二进制值。
  4. Boolean:用于存储 true 或 false。
  5. Numbers:表示数字类型,可以是整数或浮点数,如 long、integer、short、byte、double、float、half_float、scaled_float
  6. Date:表示日期类型,可以存储日期和时间信息。
  7. Object:表示 JSON 对象,可以用于存储复杂的嵌套数据结构。
  8. Nested:嵌套类型,用于表示对象数组,其中的对象可以具有自己的字段和嵌套对象。
  9. Array:数组类型,可以包含 0 个或多个值,数组中的数据类型必须相同。
  10. Range:范围类型,用于表示数字或日期的范围,如integer_range、float_range、long_range、double_range、date_range。
  11. Token Count:单词计数类型,统计字符串中的单词数量
  12. IP:IP 地址类型,用于存储和查询 IP 地址,为IPV4的地址
  13. Geo PointGeo Shape:地理位置类型,用于存储和查询地理位置和空间位置信息。其中geo_point表示经纬点,是地理点的数据类型;goe_shape是多边形的复杂地理形状。

重点:keyword和text的区别!!!

keyword text
适用场景 精确匹配场景,比如搜索用户名/唯一id 全文搜索场景,比如搜索用户个人签名
操作 可以进行聚合操作,比如对特定的字段分组、计数 支持模糊匹配,支持通配符和正则表达式
分词 不会分词 可以分词,支持定义分析器

注:如果字段存储量较大的话,两者都会影响到查询性能

创建索引

索引在es的定义相当于数据库的表,所以创建索引相当于创建表。

使用PUT方法来创建索引,下面的HTTP请求创建了一个名为user_idx的索引,其中mappings里存放的是字段,设置了每个字段的名称和类型,比如email字段是text类型,phone字段是keyword类型,birthday字段是date类型。

curl --location --request PUT 'http://localhost:9200/user_idx' \
--header 'Content-Type: application/json' \
--data '{
   
   
    "mappings":{
   
   
        "properties":{
   
   
            "email":{
   
   
                "type":"text"
            },
            "phone":{
   
   
                "type":"keyword"
            },
            "birthday":{
   
   
                "type":"date"
            }
        }
    }
}'

也可以通过settings设置基本设置,如分片数、副本数等,settings里的字段都有默认值。

添加了settings的请求如下:

curl --location --request PUT 'http://localhost:9200/user_1' \
--header 'Content-Type: application/json' \
--data '{
   
   
    "settings":{
   
   
        "number_of_shards":3,
        "number_of_replicas":2
    },
    "mappings":{
   
   
        "properties":{
   
   
            "email":{
   
   
                "type":"text"
            },
            "phone":{
   
   
                "type":"keyword"
            },
            "birthday":{
   
   
                "type":"date"
            }
        }
    }
}'

查询索引

使用GET方法来查询现有索引的定义

curl --location 'http://localhost:9200/user_idx'

返回的是索引的完整定义,创建索引的时候如果有未定义的字段,会赋默认值
image-20240305205709113.png

创建文档

通过POST方法创建文档,注意URL后面要加上_doc,表示这是对文档的操作

curl --location 'http://localhost:9200/user_idx/_doc' \
--header 'Content-Type: application/json' \
--data-raw '{
   
   
    "email":"test222@example.com",
    "phone":"1111112222",
    "birthday":"2000-01-02"
}'

查询文档

查询类型

  1. Term Query :精确查询,用于匹配字段中精确的值。
  2. Match Query:匹配查询,用于全文检索,匹配字段中包含指定文本的内容。
  3. Range Query:范围查询,用于匹配字段中值在某个指定范围内的文档。
  4. Bool Query:布尔查询,用于组合多个查询条件,支持AND、OR、NOT等逻辑关系。
  5. Match Phrase Query:短语匹配查询,根据字段中连续的短语进行查询,适用于需要保持短语顺序的查询
  6. Wildcard Query:通配符查询,用于匹配字段中包含模糊值的文档。
  7. Fuzzy Query:模糊查询,用于匹配字段中近似匹配的文本。
  8. Prefix Query:前缀查询,用于匹配字段中以指定前缀开头的文本。
  9. Phrase Query:短语匹配查询,用于匹配字段中包含特定短语的文档。
  10. Multi Match Query:多字段匹配查询,可以在多个字段中匹配指定的文本。
  11. Nested Query:嵌套查询,用于在嵌套文档中进行查询。
  12. Script Query:脚本查询,使用脚本来定义查询条件。

获取文档

使用GET方法和文档的id可以获取文档的详细信息

curl --location 'http://localhost:9200/user_idx/_doc/dTYHA44BgsSXhIjgILnZ'

image-20240305210125327.png

匹配查询

查询email里有test字段的数据

curl --location --request GET 'http://localhost:9200/user_idx/_search' \
--header 'Content-Type: application/json' \
--data '{
   
   
    "query":{
   
   
        "match":{
   
   
            "email":"test"
        }
    }
}'

image-20240305210510931.png

精确匹配

term表示精确匹配,下面的HTTP请求表示查询phone字段为1112222的数据

curl --location --request GET 'http://localhost:9200/user_idx/_search' \
--header 'Content-Type: application/json' \
--data '{
   
   
    "query":{
   
   
        "term":{
   
   
            "phone":"1112222"
        }
    }
}'

image-20240305210744322.png

范围查询

range表示返回查询,下面的请求表示查询birthday大于等于1900-01-11的数据。

范围查询里的字段:

  • gt:大于(Greater-than)
  • gte:大于或等于(Greater-than or equal to)
  • lt:小于(Less-than)
  • lte:小于或等于(Less-than or equal to)
curl --location --request GET 'http://localhost:9200/user_idx/_search' \
--header 'Content-Type: application/json' \
--data '{
   
   
    "query":{
   
   
        "range":{
   
   
            "birthday":{
   
   
                "gte":"1900-01-11"
            }
        }
    }
}'

image-20240305210851873.png

Go 使用ElasticSearch

官方库是 github.com/elastic/go-elasticsearch/v8

一般用的库是 github.com/olivere/elastic/v7

更推荐后者,更好用一些,很多公司都是用的这个库

import (
    elastic "github.com/elastic/go-elasticsearch/v8"
    olivere "github.com/olivere/elastic/v7"
)

初始化客户端

都是调用NewClient方法,传入地址即可,两者区别不大

es, err := elastic.NewClient(elastic.Config{
   
   
        Addresses: []string{
   
   "http://localhost:9200"},
})

ol, err := olivere.NewClient(olivere.SetURL("http://localhost:9200"))

创建索引

其中es为刚刚使用官方库创建的client,ol为刚刚使用三方库创建的client。

下面代码的def为索引配置的json格式,即

    def := `
{  
  "settings": {  
    "number_of_shards": 3,  
    "number_of_replicas": 2  
  },  
  "mappings": {  
    "properties": {
      "email": {  
        "type": "text"  
      },  
      "phone": {  
        "type": "keyword"  
      },  
      "birthday": {  
        "type": "date"  
      }
    }  
  }  
}
`
resp, err := es.Indices.Create("user_idx_go",es.Indices.Create.WithContext(ctx),es.Indices.Create.WithBody(strings.NewReader(def)))

_, err = ol.CreateIndex("user_idx_go_ol").Body(def).Do(ctx)

创建文档

创建文档对应的API是Index,索引对应的是Indices。注意两者的区别

官方库需要构建json字符串,如下面代码的data,而三方库则可以传入结构体,稍微简化了一下代码

data := `
{  
  "email": "john@example.com",  
  "phone": "1234567890",  
  "birthday": "2000-01-01"  
}
`
    _, err := es.Index("user_idx_go", strings.NewReader(data), es.Index.WithContext(ctx))


    _, err = ol.Index().Index("user_idx_go").BodyJson(User{
   
   Email: "john@example.com"}).Do(ctx)

查询文档

注意:如果是根据文档id查找的话使用GET这个API,如果想要根据条件查询使用Search这个API,跟直接操作es类似。

官方库需要构造query的json格式请求,返回的结果是类似http的返回体,需要自己构造解析,非常麻烦。

image-20240305212344040.png

三方库则有对应的函数,比如NewMatchQuery。返回结果是已经定义的结构体,结果在hits里。

query := `
{  
  "query": {  
    "range": {  
      "birthday": {
        "gte": "1990-01-01"
      }
    }  
  }  
}
`
resp1, err := es.Search(es.Search.WithContext(ctx),es.Search.WithIndex("user_idx_go"),es.Search.WithBody(strings.NewReader(query)))


olQuery := olivere.NewMatchQuery("email", "john")
resp, err := s.olivere.Search("user_idx_go").Query(olQuery).Do(ctx)
for _, hit := range resp.Hits.Hits {
   
   
    var u User
    err = json.Unmarshal(hit.Source, &u)

}
相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
3月前
|
JSON 安全 前端开发
类型安全的 Go HTTP 请求
类型安全的 Go HTTP 请求
|
14天前
|
网络协议 安全 Go
Go语言进行网络编程可以通过**使用TCP/IP协议栈、并发模型、HTTP协议等**方式
【10月更文挑战第28天】Go语言进行网络编程可以通过**使用TCP/IP协议栈、并发模型、HTTP协议等**方式
43 13
|
1月前
使用Netty实现文件传输的HTTP服务器和客户端
本文通过详细的代码示例,展示了如何使用Netty框架实现一个文件传输的HTTP服务器和客户端,包括服务端的文件处理和客户端的文件请求与接收。
38 1
使用Netty实现文件传输的HTTP服务器和客户端
|
3月前
|
数据采集 缓存 IDE
Go中遇到http code 206和302的获取数据的解决方案
文章提供了解决Go语言中处理HTTP状态码206(部分内容)和302(重定向)的方案,包括如何获取部分数据和真实请求地址的方法,以便程序员能快速完成工作,享受七夕时光。
166 0
Go中遇到http code 206和302的获取数据的解决方案
|
3月前
|
开发者 Python
深入解析Python `httpx`源码,探索现代HTTP客户端的秘密!
深入解析Python `httpx`源码,探索现代HTTP客户端的秘密!
87 1
|
3月前
|
程序员 Go 网络架构
不看就落后了,Go 1.22 中更好的http router
不看就落后了,Go 1.22 中更好的http router
|
4月前
|
SQL JavaScript 前端开发
函数计算操作报错合集之HTTP触发器报404错误,是什么导致的
Serverless 应用引擎(SAE)是阿里云提供的Serverless PaaS平台,支持Spring Cloud、Dubbo、HSF等主流微服务框架,简化应用的部署、运维和弹性伸缩。在使用SAE过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
3月前
|
运维 安全 网络协议
运维.索引引擎ElasticSearch.记录一个小异常:received plaintext http traffic on an https channel
运维.索引引擎ElasticSearch.记录一个小异常:received plaintext http traffic on an https channel
259 0
|
3月前
|
JSON 测试技术 Go
Go Kit中读取原始HTTP请求体的方法
Go Kit中读取原始HTTP请求体的方法
|
3月前
|
网络协议 Go
go的net/http有哪些值得关注的细节?
go的net/http有哪些值得关注的细节?