文章目录
Elasticsearch查询
上一篇文章我们构建好了一些具体的数据,那么有了数据,按照最常见的思路,就是对数据进行修改、删除、查询。
写在前面
对于ES查询,有的人不知道从哪里下手,那就把它当做一个数据库,想想平时我们开发的时候针对数据库的查询都基本有哪些,就找到思路了。有了思路再去看对应的文档,就快的多了。
查询更多的是要对官方Query DSL很熟悉,起码要知道,当前业务查询应该使用哪种查询,快速查阅文档。根据官方DSL文档目录可知,有全文索引、Term(术语)级别的索引,还有基于地理位置的索引,各种各样。需要我们对这些索引类型熟记于心,并知道哪个field的哪个fieldType需要使用哪种类型的索引
熟练的掌握DSL不仅可以使我们更快的查询数据,在日后的使用ES的Java API编程中也有很多帮助
es查询多以_search结尾
简单查询
查询总数
我想看看当前index里一共有多少篇文章
GET /my-articles/_count
查询所有
查询所有文章
GET /my-articles/_search
分页查询
文章数据会随着我们的业务越来越多,那么这时候就需要分页展示数据
每页两条数据
GET /my-articles/_search
{
"from": 1,
"size": 2
}
根据ID查询
平时开发中,可能会根据一个或者多个ID进行
根据一个ID查询
GET /my-articles/_doc/FoGzCXoBZpqt44v39dwJ
根据批量ID查询-Multi get,mget官方文档,有三种方式,个人比较喜欢使用下面这种
GET /my-articles/_mget
{
"ids":["dBCh0XkBokVGPLgUdSlh","FoGzCXoBZpqt44v39dwJ"]
}
GET /my-articles/_search
{
"query":{
"ids":{
"values":["dBCh0XkBokVGPLgUdSlh","FoGzCXoBZpqt44v39dwJ"]
}
}
}
查询结果排序
对文章进行排序
使用sort参数,格式为filed:asc/desc,如果是多个field排序,用逗号隔开
GET /my-articles/_search?sort=creted:desc,reading_count:asc
还有下面这种方式
GET /my-articles/_search
{
"sort":[
{
"created":{
"order":desc
}
}
]
}
只查部分filed
平时查询可能不会用到一个document中的所有field,我可能只想查业务需要的部分field
多个字段用逗号分隔
第一种方式
GET /my-articles/_search?_source_includes=title,author,article_content
第二种方式
search RequestBody参数说明
GET /my-articles/_search
{
"source":{
"includes":["title","author","article_content"]
}
}
第三种方式
GET /my-articles/_search
{
"query": {
"match_all": {}
},
"fields": [
"title","article_content"
],
"_source": false
}
高级查询
Query Context
在Elasticsearch查询中,基本有两种方式,一种是所有查询参数放在GET的parameter中,还有一种放在Request body中的,这两种方式看个人喜好.在使用Request body这种方式的时候,用到最多的就是Query Context.熟练query context的各种组合很有必要
模糊查询
fuzzy
模糊查询可用于返回包含与搜索词相似的词的文档。注意这里的模糊查询不等同于SQL中like查询
GET /my-articles/_search
{
"query":{
"fuzzy":{
"article_content":{
"value":"nglishcontent"
}
}
}
}
注意:看了官方关于fuzzy的文档,很多人还是对于fuzzy一头雾水,不知道,es究竟怎么处理fuzzy的,这里分享一篇解释fuzzy的文章,写的特别清晰,相信你一看就明白了
wildcard
通配符查询,才更像SQL中like查询
GET article-*/_search
{
"query": {
"bool": {
"must": [
{"wildcard": {
"article_content": {
"value": "*arTicle*",
"case_insensitive": true
}
}}
]
}
}
}
前缀查询
这里有两种方式
使用prefix
GET /my-articles/_search
{
"query": {
"prefix": {
"title": {
"value": ""
}
}
}
}
对于text类型的使用match_phrase_prefix
GET /my-articles/_search
{
"query": {
"match_phrase_prefix": {
"title": "清"
}
}
}
短语查询
为什么会有短语查询呢?有过搜索引擎经验的开发基本知道,搜索引擎会把数据进行分词处理,一个句子 ”晓看红湿处,花重锦官城“。可能被分成多个部分。那么当我们呢只想查”花重锦官城“根据分词结果,搜索引擎可能会把包括花、官城这类内容也查出来,这是我们不想看到的。所以有了短语查询
如果要查询的field的是text类型的,可以使用match_parse
GET /my-articles/_search
{
"query":{
"match_phrase":{
"title":{
"value":"青玉案"
}
}
}
}
完全匹配查询
使用term
GET /my-articles/_search
{
"query":{
"term":{
"articlet_content":{
"value":"englishcontent"
}
}
}
}
范围查询
使用range
GET /my-articles/_search
{
"query":{
"range":{
"created":{
"gte":"2021-06-03 15:20:14",
"lte":"2021-06-25 19:27:56"
}
}
}
}
复合查询
上面的查询都是一个的,如果多个条件组合则使用复合查询
GET /my-articles/_search
{
"query":{
"bool":{
"must":[
{
"prefix": {
"title": {
"value": "english"
}
}
},
{
"prefix": {
"author": {
"value": "d"
}
}
}
]
}
}
}
忽略富文本查询
在当前例子中,有一个场景可能需要我们做特殊处理,如果为了文章内容显示好看,可能会加一些HTML标签,组成富文本。但是我们在真正查询的时候希望ES不要把这些标签也当做分词来使用,那么这时候我们就需要针对当前的分词器加一些filter,这个部分打算放在后续分词器部分说明。这里只是提醒读者实际业务场景中很有可能出现这种场景
备注
上面的示例中,有的查询用了中文,有的用了英文,是因为ES官方内置的默认的分词器对中文支持不是太好,所以演示的时候,针对一个具体的场景,可能需要使用英文内容。和忽略HTML那里一样,在后续分词器的部分会统一进行完善
好用的文档
- Elasticsearch 官方 Search API
- Elasticsearch官方 Query DSL
- Elasticsearch官方CSDN博客-查询示例文章
思维导图
下一篇文章将介绍对于document的其他操作,如修改数据、删除数据、修改field的type等