前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go Elasticsearch 查询快速入门

Go Elasticsearch 查询快速入门

作者头像
恋喵大鲤鱼
发布2021-12-06 10:48:02
8.6K0
发布2021-12-06 10:48:02
举报
文章被收录于专栏:C/C++基础
在这里插入图片描述
在这里插入图片描述

文章目录

0.前言

搜索是 ES 最为复杂精妙的地方,这里只示例项目中较为常用的查询。

ES 中的条件查询常用的有如下几种:

  • TermQuery 精确匹配单个字段
  • TermsQuery 精确匹配单个字段,但使用多值进行匹配,类似于 SQL 中的 in 操作
  • MatchQuery 单个字段匹配查询(匹配分词结果,不需要全文匹配)
  • RangeQuery 范围查询
  • BoolQuery 组合查询

1.根据 ID 查询

根据文档ID获取单个文档信息。

代码语言:javascript
复制
// GetByID4ES 根据ID查询单个文档
func GetByID4ES(ctx context.Context, index, id string) (string, error) {
	res, err := GetESClient().Get().Index(index).Id(id).Do(ctx)
	if err != nil {
		return "", err
	}
	return string(res.Source), nil
}

注意:查询不存在的 ID,会报elastic: Error 404 (Not Found)错误。

对应的 RESTful api 为:

代码语言:javascript
复制
GET /es_index_userinfo/_doc/1
在这里插入图片描述
在这里插入图片描述

如果只想返回部分字段,可以使用_source_includes_source_excludes参数来包括或过滤掉特定字段。

例如不返回创建时间(create_time) 和更新时间(update_time),支持通配符。

代码语言:javascript
复制
GET /es_index_userinfo/_doc/1?_source_includes=*&_source_excludes=*time

2.精确匹配单个字段

比如获指定用户名的用户。

代码语言:javascript
复制
// 创建 term 查询条件,用于精确查询
termQuery := elastic.NewTermQuery("username", "cat")
searchResult, err := GetESClient().Search().
	Index("es_index_userinfo"). 			// 设置索引名
	Query(termQuery).           			// 设置查询条件
	Sort("create_time", true).    			// 设置排序字段,根据 create_time 字段升序排序
	From(0).                    			// 设置分页参数 - 起始偏移量,从第 0 行记录开始
	Size(10).                   			// 设置分页参数 - 每页大小
	Do(ctx)                     			// 执行请求

对应的 RESTful api 为:

代码语言:javascript
复制
GET /es_index_userinfo/_search
{
  "query": {
    "term": {"username": "bob"}
  },
  "sort": [
    {"create_time": "asc"}
  ],
  "from": 0,
  "size":10
}

注意: term 精确匹配 text 类型的字段可能匹配不到,因为 text 类型的字段会被分词,如果分词的结果中不包含整个字段内容,那么将无法匹配,因为 term 匹配是和分词的结果匹配。keyword 类型字段不会进行分词,所以可以用 term 进行精确匹配。

解决办法:给 text 类型的字段取一个别名,别名的类型为 keyword,即不进行分词。

代码语言:javascript
复制
"ancestral":{                 
    "type": "text",         
    "fields": {             
      "alias": {          
        "type": "keyword"
      }
    }
}

那么可以通过 ancestral.alias 访问字段 ancestral,其类型设为 keyword。

3.精确匹配单个字段的多个值

通过 TermsQuery 实现单个字段的多值精确匹配,类似于 SQL 的 in 查询。

比如获指定用户名的用户,只需要命中一个即可。

代码语言:javascript
复制
// 创建 terms 查询条件,用于多值精确查询
termsQuery := elastic.NewTermsQuery("username", "cat", "bob")
searchResult, err := GetESClient().Search().
	Index("es_index_userinfo"). 			// 设置索引名
	Query(termsQuery).           			// 设置查询条件
	Sort("create_time", true).    			// 设置排序字段,根据 create_time 字段升序排序
	From(0).                    			// 设置分页参数 - 起始偏移量,从第 0 行记录开始
	Size(10).                   			// 设置分页参数 - 每页大小
	Do(ctx)                     			// 执行请求

对应的 RESTful api 为:

代码语言:javascript
复制
GET /es_index_userinfo/_search
{
  "query": {
    "terms": {"username": ["bobs","bob"]}
  },
  "sort": [
    {"create_time": "asc"}
  ],
  "from": 0,
  "size":10
}

4.全文查询

全文查询 Full text queries 是个 ES 的核心查询。

无论需要查询什么字段, MatchQuery 查询都应该会是首选的查询方式。它是一个高级全文查询 ,这表示它既能处理全文字段,又能处理精确字段。

使用 MatchQuery 对字段进行全文搜索,即匹配分词结果。如果分词出现在 MatchQuery 中指定的内容(指定的内容也会分词),如果存在相同的分词,则匹配。

假设“我爱中国”的分词结果为“我”、“爱”、“中国”,那么搜索“我是第一名”也会匹配,因为“我是第一名”的分词结果中也有“我”。

ES 查看某个字段数据的分词结果。

代码语言:javascript
复制
GET /{index}/{type}/{id}/_termvectors?fields={fields_name}

注意: (1)如果想对输入不进行分词,请使用 term query; (2)如果想对输入的分词结果全部匹配,请使用 match phrase query; (3)如果想对输入的分词结果全部匹配且最后一个分词支持前缀匹配,请使用 match phrase prefix query; (4)如果是对 keyword 字段进行 MatchQuery,因为该类型不会分词,所以是精确匹配。

比如获取指定用户名的用户。

代码语言:javascript
复制
// 创建 match 查询条件
matchQuery := elastic.NewMatchQuery("username", "bob")
searchResult, err := GetESClient().Search().
	Index("es_index_userinfo"). // 设置索引名
	Query(matchQuery).          // 设置查询条件
	Sort("create_time", true).  // 设置排序字段,根据 create_time 字段升序排序
	From(0).                    // 设置分页参数 - 起始偏移量,从第 0 行记录开始
	Size(10).                   // 设置分页参数 - 每页大小
	Do(ctx)                     // 执行请求

对应的 RESTful api 为:

代码语言:javascript
复制
GET /es_index_userinfo/_search
{
  "query": {
    "match": {"username": "bob"}
  },
  "sort": [
    {"create_time": "asc"}
  ],
  "from": 0,
  "size":10
}

5.范围查询

实现类似age >= 18 and age < 35的范围查询条件。

代码语言:javascript
复制
// 创建 range 查询条件
rangeQuery := elastic.NewRangeQuery("age").Gte(18).Lte(35)
searchResult, err := GetESClient().Search().
	Index("es_index_userinfo"). // 设置索引名
	Query(rangeQuery).          // 设置查询条件
	Sort("create_time", true).  // 设置排序字段,根据 create_time 字段升序排序
	From(0).                    // 设置分页参数 - 起始偏移量,从第 0 行记录开始
	Size(10).                   // 设置分页参数 - 每页大小
	Do(ctx)                     // 执行请求

对应的 RESTful api 为:

代码语言:javascript
复制
GET /es_index_userinfo/_search
{
  "query": {
    "range":{"age" : {"gte" : 18, "lte": 35}}
  },
  "sort": [
    {"create_time": "asc"}
  ],
  "from": 0,
  "size":10
}

6.bool 组合查询

BoolQuery 是一种组合查询,将多个条件通过类似 SQL 语句 and 和 or 组合在一起来作为查询条件。

其有四种类型的子句:

类型

描述

must

条件必须要满足,并将对分数起作用

filter

条件必须要满足,但又不同于 must 子句,在 filter context 中执行,这意味着忽略评分,并考虑使用缓存。效率会高于 must

should

条件应该满足。可以通过 minimum_should_match 参数指定应该满足的条件个数。如果 bool 查询包含 should 子句,并且没有 must 和 filter 子句,则默认值为 1,否则默认值为 0

must_not

条件必须不能满足。在 filter context 中执行,这意味着评分被忽略,并考虑使用缓存。因为评分被忽略,所以会返回所有 0 分的文档

must

类似 SQL 的 and,代表必须匹配的条件。

代码语言:javascript
复制
	// 创建 bool 查询
	boolQuery := elastic.NewBoolQuery()

	// 创建查询条件
	termQuery := elastic.NewTermQuery("username", "bob")
	rangeQuery := elastic.NewRangeQuery("age").Gte(18).Lte(35)

	// 设置 bool 查询的 must 条件, 组合了两个子查询
	// 搜索用户名为 bob 且年龄在 18~35 岁的用户
	boolQuery.Must(termQuery, rangeQuery)

	searchResult, err := GetESClient().Search().
		Index("es_index_userinfo"). // 设置索引名
		Query(boolQuery).           // 设置查询条件
		Sort("create_time", true).  // 设置排序字段,根据 create_time 字段升序排序
		From(0).                    // 设置分页参数 - 起始偏移量,从第 0 行记录开始
		Size(10).                   // 设置分页参数 - 每页大小
		Do(ctx)                     // 执行请求

对应的 RESTful api 为:

代码语言:javascript
复制
GET /es_index_userinfo/_search
{
  "query":{
    "bool":{
      "must":[
        {"term":{"username": "bob"}},
        {"range":{"age":{"gte":18, "lte":35}}}
      ]
    }
  },
  "sort": [
    {"create_time": "asc"}
  ],
  "from": 0,
  "size":10
}

filter

类似 SQL 的 and,代表必须匹配的条件。不计算匹配分值,且子句被考虑用于缓存。

使用 filter 替代 must 条件,查询用户名为 bob 且年龄在 18~35 岁的用户

代码语言:javascript
复制
	// 创建 bool 查询
	boolQuery := elastic.NewBoolQuery()

	// 创建查询条件
	termQuery := elastic.NewTermQuery("username", "bob")
	rangeQuery := elastic.NewRangeQuery("age").Gte(18).Lte(35)

	// 设置 bool 查询的 filter 条件, 组合了两个子查询
	// 搜索用户名为 bob 且年龄在 18~35 岁的用户
	boolQuery.Filter(termQuery, rangeQuery)

	searchResult, err := GetESClient().Search().
		Index("es_index_userinfo"). // 设置索引名
		Query(boolQuery).          // 设置查询条件
		Sort("create_time", true).  // 设置排序字段,根据 create_time 字段升序排序
		From(0).                    // 设置分页参数 - 起始偏移量,从第 0 行记录开始
		Size(10).                   // 设置分页参数 - 每页大小
		Do(ctx)                     // 执行请求

对应的 RESTful api 为:

代码语言:javascript
复制
GET /es_index_userinfo/_search
{
  "query":{
    "bool":{
      "filter":[
        {"term":{"username": "bob"}},
        {"range":{"age":{"gte":18, "lte":35}}}
      ]
    }
  },
  "sort": [
    {"create_time": "asc"}
  ],
  "from": 0,
  "size":10
}

should

类似 SQL 中的 or, 可以通过 minimum_should_match 参数指定应该满足的条件个数。如果 bool 查询包含 should 子句,并且没有 must 和 filter 子句,则默认值为 1,否则默认值为 0。

比如查询用户名为 bob 且年龄为18 或 35 岁的用户。

代码语言:javascript
复制
// 创建 bool 查询
boolQuery := elastic.NewBoolQuery()

// 创建查询条件
termQuery := elastic.NewTermQuery("username", "bob")
termQuery1 := elastic.NewTermQuery("age", 18)
termQuery2 := elastic.NewTermQuery("age", 35)

// 设置 bool 查询的 filter 条件, 组合了两个子查询
// 搜索用户名为 bob 且年龄为 18 或 35 岁的用户
boolQuery.Filter(termQuery, termQuery)
boolQuery.Should(termQuery, termQuery1, termQuery2)
boolQuery.MinimumNumberShouldMatch(1) // 至少满足 should 中的一个条件

searchResult, err := GetESClient().Search().
	Index("es_index_userinfo"). // 设置索引名
	Query(boolQuery).           // 设置查询条件
	Sort("create_time", true).  // 设置排序字段,根据 create_time 字段升序排序
	From(0).                    // 设置分页参数 - 起始偏移量,从第 0 行记录开始
	Size(10).                   // 设置分页参数 - 每页大小
	Do(ctx)                     // 执行请求

对应的 RESTful api 为:

代码语言:javascript
复制
GET /es_index_userinfo/_search
{
  "query":{
    "bool":{
      "filter": {"term":{"username": "bob"}},
      "should":[
        {"term":{"age":18}},
        {"term":{"age":35}}
      ],
      "minimum_should_match" : 1
    }
  },
  "sort": [
    {"create_time": "asc"}
  ],
  "from": 0,
  "size":10
}

must_not

跟 must 作用相反,表示条件必须不能满足。

比如搜索用户名为 bob 且年龄不为 18 或 35 岁的用户。

代码语言:javascript
复制
	// 创建 bool 查询
	boolQuery := elastic.NewBoolQuery()

	// 创建查询条件
	termQuery := elastic.NewTermQuery("username", "bob")
	termQuery1 := elastic.NewTermQuery("age", 18)
	termQuery2 := elastic.NewTermQuery("age", 35)

	// 设置 bool 查询的 filter 条件, 组合了两个子查询
	// 搜索用户名为 bob 且年龄不为 18 和 35 岁的用户
	boolQuery.Filter(termQuery)
	boolQuery.MustNot(termQuery1, termQuery2)

	searchResult, err := GetESClient().Search().
		Index("es_index_userinfo"). // 设置索引名
		Query(boolQuery).           // 设置查询条件
		Sort("create_time", true).  // 设置排序字段,根据 create_time 字段升序排序
		From(0).                    // 设置分页参数 - 起始偏移量,从第 0 行记录开始
		Size(10).                   // 设置分页参数 - 每页大小
		Do(ctx)                     // 执行请求

对应的 RESTful api 为:

代码语言:javascript
复制
GET /es_index_userinfo/_search
{
  "query":{
    "bool":{
      "filter": {"term":{"username": "bob"}},
      "must_not":[
        {"term":{"age":18}},
        {"term":{"age":35}}
      ]
    }
  },
  "sort": [
    {"create_time": "asc"}
  ],
  "from": 0,
  "size":10
}

7.分页查询

我们也可以根据条件分页查询。

ES 分页搜索一般有三种方案,from + size、search after、scroll api,这三种方案分别有自己的优缺点。

from + size

这是 ES 分页中最常用的一种方式,与 MySQL 类似,from 指定起始位置,size 指定返回的文档数。

这种分页方式,在分布式的环境下的深度分页是有性能问题的,一般不建议用这种方式做深度分页,可以用下面将要介绍的两种方式。

理解为什么深度分页是有问题的,假设取的页数较大时(深分页),如请求第20页,Elasticsearch 不得不取出所有分片上的第 1 页到第 20 页的所有文档,并做排序,最终再取出 from 后的 size 条结果作爲最终的返回值。

所以,当索引记录非常非常多(千万或亿),是无法使用 from + size 做深分页的,分页越深则越容易 OOM。即便不 OOM,也很消耗 CPU 和内存资源。

所以 ES 为了避免深分页,不允许使用 from + size 的方式查询 1 万条以后的数据,即 from + size 大于 10000 会报错,不过可以通过 index.max_result_window 参数进行修改。

代码语言:javascript
复制
// GetByQueryPage4ES 分页查询
// param: index 索引; query 查询条件; page 起始页(从 1 开始); size 页大小
func GetByQueryPage4ES(ctx context.Context, index string, query elastic.Query, page, size int) ([]string, error) {
	start := (page - 1) * size
	res, err := GetESClient().Search(index).Query(query).From(start).Size(size).Do(ctx)
	if err != nil {
		return nil, err
	}
	sl := make([]string, 0, res.TotalHits())
	for _, hit := range res.Hits.Hits {
		sl = append(sl, string(hit.Source))
	}
	return sl, nil
}

// GetByQueryPageSort4ES 根据条件分页查询 & 指定字段排序
// param: index 索引; query 查询条件; page 起始页(从 1 开始); size 页大小; field 排序字段; ascending 升序
func GetByQueryPageSort4ES(ctx context.Context, index string, query elastic.Query, page, size int, field string,
	ascending bool) ([]string, error) {
	from := (page - 1) * size
	res, err := GetESClient().Search(index).Query(query).Sort(field, ascending).From(from).Size(size).Do(ctx)
	if err != nil {
		return nil, err
	}
	sl := make([]string, 0, res.TotalHits())
	for _, hit := range res.Hits.Hits {
		sl = append(sl, string(hit.Source))
	}
	return sl, nil
}

比如分页查询年龄 >=18 且按照创建时间降序排序:

代码语言:javascript
复制
query := elastic.NewBoolQuery()
query.Filter(elastic.NewRangeQuery("age").Gte(18))
sl, err := GetByQueryPageSort4ES(context.Background(), index, query, 1, 500, "create_time", false)

对应的 RESTful api 为:

代码语言:javascript
复制
GET /es_index_userinfo/_search
{
	"query": {
		"bool": {
			"filter":[{"range" : {"age" : {"gte" : 18}}}]
		}
	},
	"from": 0, 
	"size" : 500,
	"sort" : [{"create_time":"desc"}]
}

注意:如果想控制返回哪些字段,可以使用 _source 来指定。比如只返回用户名(username)和年龄(age)。

代码语言:javascript
复制
GET /es_index_userinfo/_search
{
	"query": {
		"bool": {
			"filter":[{"range" : {"age" : {"gte" : 18}}}]
		}
	},
	"from": 0, 
	"size" : 500,
	"sort" : [{"create_time":"desc"}],
	"_source": ["username", "age"]
}

Go 代码带上_source的方式。

代码语言:javascript
复制
fsc := elastic.NewFetchSourceContext(true).Include("username", "age")
GetESClient().Search(index).Query(query).FetchSourceContext(fsc).Sort(field, ascending).From(from).Size(size).Do(ctx)

search after

search after 利用实时有游标来帮我们解决实时滚动的问题。

第一次搜索时需要指定 sort,并且保证值是唯一的,可以通过加入 _id 保证唯一性。

比如获取籍贯为安徽的用户,且按照创建时间降序。

代码语言:javascript
复制
matchQuery := elastic.NewMatchQuery("ancestral", "安徽")

// 查询第一页(无需指定 SearchAfter)
searchResult, err := GetESClient().Search().
	Index("es_index_userinfo"). // 设置索引名
	Query(matchQuery).          // 设置查询条件
	Sort("create_time", false). // 按照创建时间降序
	Size(1000).                 // 设置分页参数
	Do(ctx)

// 查询第 n 页(n > 1,需要指定 SearchAfter)
searchResult, err := GetESClient().Search().
	Index("es_index_userinfo").  		// 设置索引名
	Query(matchQuery).           		// 设置查询条件
	Sort("create_time", false).  		// 按照创建时间降序
	SearchAfter(lastCreateTime, id). 	// 上页最后一条的创建时间和 ID
	Size(1000).                  		// 设置分页参数
	Do(ctx)

对应 RESTful api 的示例。

代码语言:javascript
复制
GET es_index_userinfo/_search
{
  "size": 1,
  "query": {
    "match": {"ancestral": "安徽"}
  },
  "sort": [
    {"create_time": "desc"},
    {"_id": "desc"}
  ]
}

在返回的结果中,最后一个文档有类似下面的数据,由于我们排序用的是两个字段,返回的是两个值。

代码语言:javascript
复制
"sort" : [
	1627522828,
	"2"
]

第二次搜索,带上这个 sort 信息即可,如下:

代码语言:javascript
复制
GET es_index_userinfo/_search
{
  "size": 1,
  "query": {
    "match": {"ancestral": "安徽"}
  },
  "sort": [
    {"create_time": "desc"},
    {"_id": "desc"}
  ],
  "search_after": [
    1627522828,
    "2"
  ]
}

scroll api

创建一个快照,有新的数据写入以后,无法被查到。每次查询后,输入上一次的 scroll_id。目前官方已经不推荐使用这个 API 了,使用search_after 即可。

Go 代码示例:

代码语言:javascript
复制
// GetByQueryPageSortScroll4ES 获取第一页数据 & 获取游标ID
// ret: 文档切片, 游标ID, error
func GetByQueryPageSortScroll4ES(ctx context.Context, index string, query elastic.Query, size int, field string,
ascending bool) ([]string, string, error) {
	res, err := GetESClient().Scroll(index).Query(query).Sort(field, ascending).Size(size).Do(ctx)
	if err != nil {
		return nil, "", err
	}
	sl := make([]string, 0, res.TotalHits())
	for _, hit := range res.Hits.Hits {
		sl = append(sl, string(hit.Source))
	}
	return sl, res.ScrollId, nil
}

// GetByQScrollID4ES 根据游标 ID 获取下一页
func GetByQScrollID4ES(ctx context.Context, scrollID string) ([]string, error) {
	res, err := GetESClient().Scroll().ScrollId(scrollID).Do(ctx)
	if err != nil {
		return nil, err
	}
	sl := make([]string, 0, res.TotalHits())
	for _, hit := range res.Hits.Hits {
		sl = append(sl, string(hit.Source))
	}
	return sl, nil
}

首先需要获取第一页数据并获取游标ID,然后便可以根据游标 ID 继续获取下一页数据,如果下一页如果为空的话会报 EOF 错误,此时便可知拉取结束了。

比如我们还是要分页获取籍贯为安徽的用户,且按照创建时间降序。

代码语言:javascript
复制
GET es_index_userinfo/_search?scroll=1m
{
  "size": 1,
  "query": {
    "match": {"ancestral": "安徽"}
  },
  "sort": [
    {"create_time": "desc"}
  ]
}

在返回的数据中,有一个 _scroll_id 字段,下次搜索的时候带上这个数据,并且使用下面的查询语句。

代码语言:javascript
复制
POST _search/scroll
{
  "scroll" : "1m",
  "scroll_id" : "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFFRpdno4bm9CU3A1TEhvY3ktQjZzAAAAAAKolSoWbm04UWQ5SHlRdDJRRjZaeGFBdjFEQQ=="
}

上面的 scroll 指定搜索上下文保留的时间,1m 代表 1 分钟,还有其他时间可以选择,有 d、h、m、s 等,分别代表天、时、分钟、秒。

搜索上下文有过期自动删除,但如果自己知道什么时候该删,可以自己手动删除,减少资源占用。

代码语言:javascript
复制
DELETE /_search/scroll
{
  "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAA6UWWVJRTk9TUXFTLUdnU28xVFN6bEM4QQ=="
}

小结

from + size 的优点是简单,缺点是在深度分页的场景下系统开销比较大。

search after 可以实时高效的进行分页查询,但是它只能做下一页这样的查询场景,不能随机的指定页数查询。

scroll api 方案也很高效,但是它基于快照,不能用在实时性高的业务场景,且官方已不建议使用。

8.查询文档是否存在

借助 ExistsService 使用 HEAD 检查文档是否存在判断。

如果文档存在, Elasticsearch 将返回一个 200 ok 的状态码,若文档不存在, Elasticsearch 将返回一个 404 Not Found 的状态码。

8.1 根据ID判断文档是否存在

代码语言:javascript
复制
// IsDocExists 某条记录是否存在
func IsDocExists(ctx context.Context, id, index string) (bool, error) {
	return GetESClient().Exists().Index(index).Id(id).Do(ctx)
}

RESTful api 示例:

代码语言:javascript
复制
head es_index_userinfo/_doc/1

返回:

代码语言:javascript
复制
200 - OK

8.2 查询符合条件的文档数量

可以借助 CountService 查询符合条件的文档数量,进而判断文档是否存在。

比如查询年龄>=18的用户数量。

代码语言:javascript
复制
	// 创建 range 查询条件
	rangeQuery := elastic.NewRangeQuery("age").Gte(18)
	cnt, err := GetESClient().
		Count("es_index_userinfo").
		Query(rangeQuery).
		Do(ctx)

RESTful api 示例:

代码语言:javascript
复制
GET es_index_userinfo/_count
{
    "query": {
    "range": {
        "age": {"gte" : 18}
    }
  }
}

9.获取文档数量

上一节已经说了可以借助 CountService 查询符合条件的文档数量,如果想查询 index 下的所有文档呢?

很简单,不指定条件即可。

代码语言:javascript
复制
// GetIndexDocNum 获取索引文档总数
func GetIndexDocNum(ctx context.Context, index string) (int64, error) {
	return GetESClient().Count(index).Do(ctx)
}

RESTful api 示例:

代码语言:javascript
复制
GET es_index_userinfo/_count

# 示例结果
{
  "count" : 337,
  "_shards" : {
    "total" : 20,
    "successful" : 20,
    "skipped" : 0,
    "failed" : 0
  }
}

参考文献

github/elastic/elasticsearch github/olivere/elastic/v7 pkg.go.dev/github.com/olivere/elastic/v7 掘金.Elasticsearch 分页查询 golang elasticsearch 查询教程 CSDN.ES中如何对text字段进行精确匹配 知乎.一文搞懂match、match_phrase与match_phrase_prefix的检索过程 elastic type CountService elastic type ExistsService Elasticsearch Guide [7.15] » Query DSL » Full text queries » Match query Elasticsearch Guide [7.15] » Query DSL » Full text queries » Match query Elasticsearch Guide [7.15] » Query DSL » Full text queries » Match phrase query [Elasticsearch Guide [7.15] » Query DSL » Full text queries » Match phrase prefix query]((https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query-phrase-prefix.html) Elasticsearch Guide [7.15] » REST APIs » Search APIs » Count API

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/10/22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 0.前言
  • 1.根据 ID 查询
  • 2.精确匹配单个字段
  • 3.精确匹配单个字段的多个值
  • 4.全文查询
  • 5.范围查询
  • 6.bool 组合查询
    • must
      • filter
        • should
          • must_not
          • 7.分页查询
            • from + size
              • search after
                • scroll api
                  • 小结
                  • 8.查询文档是否存在
                    • 8.1 根据ID判断文档是否存在
                      • 8.2 查询符合条件的文档数量
                      • 9.获取文档数量
                      • 参考文献
                      相关产品与服务
                      Elasticsearch Service
                      腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档