ElasticSearch入门四:高级查询操作一、高级查询

「这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战

系列文章:

一、高级查询操作

Elasticsearch提供了基于JSON提供完整的查询DSL来定义查询

1.1 match_all查询所有文档

GET http://127.0.0.1:9200/student/_search
{
    "query":{
        "match_all":{}
    }
}
复制代码

这里的query代表一个查询对象,里面可以有不同的查询属性。match_all是查询类型,例如:match_all(代表查询所有)、match、term、range 等等,至于 {} 里面的查询条件可以根据不同的类型,有不同的写法
返回结果的字段说明:

{
  "took" : 1116, # 查询花费的时间,单位是毫秒
  "timed_out" : false, # 操作是否超时
  "_shards" : { # 分片信息
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
     "total": {
         "value": 3,
         "relation": "eq" # eq 表示计数准确, gte表示计数不准确
     },
    "max_score" : 1.0,
    "hits" : [ # 查询命中的结果
       ...
      }
    ]
  }
}
复制代码

1.2 match匹配查询

match匹配类型查询,会把查询条件进行分词,然后进行查询,多个词条之间是or的关系。

GET http://127.0.0.1:9200/student/_search
{
  "query": {
    "match": {
        "name":"zhangsan"
    }
  }
}
复制代码

1.3 multi_match字段匹配查询

multi_match与match类似,不同的是它可以在多个字段中查询。

GET http://127.0.0.1:9200/student/_search
{
  "query": {
    "multi_match": {
        "query": "zhangsan",
        "fields": ["name","nickname"]
    }
  }
}
复制代码

查询name字段和nickname字段值为zhangsan的文档

1.4 term关键字精准查询

term查询,精确的关键词匹配查询,不对查询条件进行分词。

GET http://127.0.0.1:9200/student/_search
{
  "query": {
      "term": {
      "name": {
          "value": "zhangsan"
      }
    }
  }
}
复制代码

1.5 terms多关键字精准查询

terms 查询和 term 查询一样,但它允许你指定多值进行匹配。
如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件。

GET http://127.0.0.1:9200/student/_search
{
  "query": {
      "terms": {
         "name": {
            "value": ["zhangsan","wangwu"]
         }
      }
  }
}
复制代码

1.6 指定结果显示某些字段

默认情况下,Elasticsearch在搜索的结果中,会把文档中保存在_source的所有字段都返回。如果我们只想获取其中的部分字段,我们可以添加_source的过滤。

GET http://127.0.0.1:9200/student/_search
{
  "_source": ["name","nickname"], 
  "query": {
    "terms": {
      "nickname": ["zhangsan"]
    }
  }
}
复制代码

上面就指定了结果只显示name和nickname字段。

1.7 includes和excludes过滤字段

我们同样的可以通过:

  • includes:来指定想要显示的字段
  • excludes:来指定不想要显示的字段
GET http://127.0.0.1:9200/student/_search
{
  "_source": {
      "includes": ["name","nickname"]
  }, 
  "query": {
    "terms": {
      "nickname": ["zhangsan"]
    }
  }
}

# or

{
  "_source": {
      "excludes": ["age"]
  }, 
  "query": {
    "terms": {
      "nickname": ["zhangsan"]
    }
  }
}

复制代码

1.8 组合查询

bool把各种其它查询通过must(必须 )、must_not(必须不)、should(应该)的方式进行组合。

GET http://127.0.0.1:9200/student/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "zhangsan"
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "age": "40"
          }
        }
      ],
      "should": [
        {
          "match": {
            "sex": "男"
          }
        }
      ]
    }
  }
}
复制代码

1.9 范围查询

range 查询找出那些落在指定区间内的数字或者时间。range查询允许以下字符:

操作符 说明
gt 大于>
gte 大于等于>=
lt 小于<
lte 小于等于<=

例如查询年龄大于等于30,小于等于35

GET http://127.0.0.1:9200/student/_search
{
  "query": {
    "range": {
      "age": {
        "gte": 30,
        "lte": 35
      }
    }
  }
}
复制代码

1.10 模糊查询

返回包含与搜索字词相似的字词的文档。

编辑距离是将一个术语转换为另一个术语所需的一个字符更改的次数。这些更改可以包括:

  • 更改字符(box → fox)

  • 删除字符(black → lack)

  • 插入字符(sic → sick)

  • 转置两个相邻字符(act → cat)

为了找到相似的术语,fuzzy查询会在指定的编辑距离内创建一组搜索词的所有可能的变体或扩展。然后查询返回每个扩展的完全匹配。
通过fuzziness修改编辑距离。一般使用默认值AUTO,根据术语的长度生成编辑距离。

GET http://127.0.0.1:9200/student/_search
{
  "query": {
    "fuzzy": {
      "title": {
        "value": "zhangsan"
      }
    }
  }
}
复制代码

1.11 单字段排序

sort可以让我们按照不同的字段进行排序,并且通过order指定排序的方式。desc降序,asc升序。如下根据年龄降序排序。

GET http://127.0.0.1:9200/student/_search
{
  "query": {
    "match": {
        "name":"zhangsan"
    }
  },
  "sort": [{
    "age": {
        "order":"desc"
    }
  }]
}
复制代码

1.12 多字段排序

假定我们想要结合使用 age和 _score进行查询,并且匹配的结果首先按照年龄排序,然后按照相关性得分排序。ElasticSearch会把搜索出来的记录都会给一个评分,这里除了年龄排序之外,还根据评分排序。

GET http://127.0.0.1:9200/student/_serch
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    },
    {
      "_score":{
        "order": "desc"
      }
    }
  ]
}
复制代码

1.13 高亮查询

在进行关键字搜索时,搜索出的内容中的关键字会显示不同的颜色,称之为高亮。
Elasticsearch可以对查询内容中的关键字部分,进行标签和样式(高亮)的设置。

在使用match查询的同时,加上一个highlight属性:

  • pre_tags:前置标签
  • post_tags:后置标签
  • fields:需要高亮的字段
  • title:这里声明title字段需要高亮,后面可以为这个字段设置特有配置,也可以空
GET http://127.0.0.1:9200/student/_serch
{
  "query": {
    "match": {
      "name": "zhangsan"
    }
  },
  "highlight": {
    "pre_tags": "<font color='red'>",
    "post_tags": "</font>",
    "fields": {
      "name": {}
    }
  }
}
复制代码

1.14 分页查询

分页查询这是很常见的需求。在ElasticSearch中分页查询是这样的:from当前页的起始索引,默认是从0开始,size是每页显示多少条。

GET http://127.0.0.1:9200/student/_serch
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ],
  "from": 0,
  "size": 2
}
复制代码

1.15 聚合查询

聚合允许使用者对ElasticSearch文档进行统计分析,类似与关系型数据库中的group by,当然还有很多其他的聚合,例如取最大值、平均值等等。

GET http://127.0.0.1:9200/student/_serch
{
    "aggs":{
      "max_age":{
        "max":{"field":"age"}
      }
    },
    "size":0
}
复制代码

还有max(最大值) 例如:min(最小值)、sum(总和)、avg(平均值)、cardinality(去重后取总数)、State聚合一次性返回count、max、min、avg和sum五个指标。

1.16 桶聚合排序

桶聚和相当于sql中的group by语句。
1、分组统计

{
    "aggs":{
      "age_groupby":{
        "terms":{"field":"age"}
      }
    },
    "size":0
}
复制代码