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可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
11天前
|
存储 缓存 NoSQL
【Go语言专栏】Go语言中的Redis操作与缓存应用
【4月更文挑战第30天】本文探讨了在Go语言中使用Redis进行操作和缓存应用的方法。文章介绍了Redis作为高性能键值存储系统,用于提升应用性能。推荐使用`go-redis/redis`库,示例代码展示了连接、设置、获取和删除键值对的基本操作。文章还详细阐述了缓存应用的步骤及常见缓存策略,包括缓存穿透、缓存击穿和缓存雪崩的解决方案。利用Redis和合适策略可有效优化应用性能。
|
3天前
|
Kubernetes 关系型数据库 MySQL
实时计算 Flink版产品使用合集之在Kubernetes(k8s)中同步MySQL变更到Elasticsearch该怎么操作
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStreamAPI、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
3天前
|
存储 缓存
ETag的值是如何在HTTP响应中传递给客户端的
ETag的值是如何在HTTP响应中传递给客户端的
|
6天前
|
存储 安全 编译器
go语言中进行不安全的类型操作
【5月更文挑战第10天】Go语言中的`unsafe`包提供了一种不安全但强大的方式来处理类型转换和底层内存操作。包含两个文档用途的类型和八个函数,本文也比较了不同变量和结构体的大小与对齐系数,强调了字段顺序对内存分配的影响。
92 8
go语言中进行不安全的类型操作
|
11天前
|
Go
怎么获取客户端真实IP?GO
怎么获取客户端真实IP?GO
14 2
|
11天前
|
Java API
Java操作elasticsearch
Java操作elasticsearch
18 0
|
11天前
|
JSON 数据格式 Python
Python 的 requests 库是一个强大的 HTTP 客户端库,用于发送各种类型的 HTTP 请求
【5月更文挑战第9天】`requests` 库是 Python 中用于HTTP请求的强大工具。要开始使用,需通过 `pip install requests` 进行安装。发送GET请求可使用 `requests.get(url)`,而POST请求则需结合 `json.dumps(data)` 以JSON格式发送数据。PUT和DELETE请求类似,分别调用 `requests.put()` 和 `requests.delete()`。
36 2
|
11天前
|
Go
|
11天前
|
存储 负载均衡 Go
【Go 语言专栏】使用 Go 语言实现分布式数据库操作
【4月更文挑战第30天】本文探讨了使用Go语言实现分布式数据库操作,强调其在并发性能、网络编程、语法简洁和跨平台性上的优势。关键技术和步骤包括数据分片、数据同步、负载均衡及故障转移。通过实例分析和挑战解决,展示了Go语言在大规模数据处理中的高效与可靠性,为开发者提供指导。
|
11天前
|
存储 NoSQL Go
【Go语言专栏】Go语言中的MongoDB操作与NoSQL应用
【4月更文挑战第30天】本文介绍了Go语言中操作MongoDB的方法和NoSQL应用的优势。MongoDB作为流行的NoSQL数据库,以其文档型数据模型、高性能和可扩展性被广泛应用。在Go语言中,通过mongo-go-driver库可轻松实现与MongoDB的连接及插入、查询、更新和删除等操作。MongoDB在NoSQL应用中的优点包括灵活的数据模型、高性能、高可用性和易于扩展,使其成为处理大规模数据和高并发场景的理想选择。

热门文章

最新文章