Elasticsearch 实战 - 第四讲:ES 高级查询

  • Elasticsearch 实战系列文章:
  • 一、高级查询
  • 1、简介
  • 2、结果排序
  • 3、分页查询
  • 4、检索查询
  • 5、关键字查询
  • 6、高亮显示
  • 7、逻辑查询
  • 8、过滤查询
  • 9、分组查询

一、高级查询

1、简介

Elasticsearch基于JSON提供完整的查询DSL(Domain Specific Language:领域特定语言)来定义查询。
基本语法: GET /索引名/类型名/_search
一般都是需要配合查询参数来使用的,配合不同的参数有不同的查询效果.

参数配置项可以参考博客:https://www.jianshu.com/p/6333940621ec

2、结果排序

参数格式:

GET /索引/类型/_search
{ 
     "sort": [ 
	{field: 排序规则},
	... 
        ] 
}

排序规则:

  1. asc:表示升序
  2. desc:表示降序

没有配置排序的情况下,默认按照评分降序排列
示例如下:

GET /user/user/_search
{
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ] 
}

3、分页查询

参数格式:
from:从什么地方开始
size:到什么地方结束

GET /索引/类型/_search
{ 
      "from": start,
      "size": pageSize 
}

示例如下:

GET /product/product/_search
{
  "from": 0
  , "size": 3
}

4、检索查询

参数格式:

GET /索引/类型/_search
{
     "query": {
             检索方式: {field: value}
 }

检索方式:

  • term表示精确匹配,value值不会被分词器拆分,按照倒排索引匹配 。
  • match表示全文检索,value值会被分词器拆分,然后去倒排索引中匹配 。
  • range表示范围检索,其value值是一个对象,如{ “range”: {field: {比较规则: value, …}} } 比较规则有gt / gte / lt / lte 等。

注意:term和match都能用在数值和字符上,range多用在数值上。
示例如下:

# 查询商品中价格为 1899.99的
GET /product/_search
{
  "query": {
    "term": {
      "price": {
        "value": "1899.99"
      }
    }
  }
}

# 查询商品标题中带有鼠标,手机的
GET /product/_search
{
  "query": {
    "match": {
      "title": "小米 手机"
    }
  }
}

# 查询商品价格在1600~2800 之间的
GET /product/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 1600,
        "lte": 2800
      }
    }
  }
}

5、关键字查询

参数格式:

GET /索引/类型/_search
{
   "query": {
        "multi_match": { 
             "query": value, 
             "fields": [field1, field2, ...] 
             } 
       }  
}

multi_match:表示在多个字段间做检索,只要其中一个字段满足条件就能查询出来,多用在字符上。
示例如下:

# 查询商品产地和标题中匹配 vivo 湛江 的数据
GET /product/product/_search
{
  "query": {
    "multi_match": {
      "query": "vivo 湛江",
      "fields": ["origin","title"]
    }
  }
}

6、高亮显示

参数格式:

GET /索引/类型/_search
{ 
   "query": { ... }, 
   "highlight": {
          "fields": { 
                field1: {}, 
                field2: {}, 
                ... 
             },
           "pre_tags": 开始标签, 
           "post_tags" 结束标签
      } 
}

highlight:表示高亮显示,需要在fields中配置哪些字段中检索到该内容需要高亮显示 必须配合检索(term / match)一起使用。
示例如下:

# 查询商品标题中带有鼠标的,并且高亮显示
GET /product/_search
{
  "query": {
    "match": {
      "title": "鼠标"
    }
  },
  "highlight": {
    "fields": {
      "title": {}
    }
  }
}

7、逻辑查询

参数格式:

GET /索引/类型/_search
{
      "query": {
            "bool": {
                  逻辑规则: [ 
                   {检索方式: {field: value}},
                        ... 
                   ],
                  ... 
              } 
       } 
}

逻辑规则:must / should / must_not,相当于and / or / not
示例如下:

# 查询手机的价格在1900~2800之间的
GET /product/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "title": {
              "value": "手机"
            }
          }
        },
        {
          "range": {
            "price": {
              "gte": 1900,
              "lte": 2800
            }
          }
        }
      ]
    }
  }
}

8、过滤查询

参数格式:

GET /索引/类型/_search
{ 
    "query": {
        "bool": {
           "filter": [ 
                { 
                     检索方式: {
                           field: value 
                        } 
                }, 
                ... 
             ] 
          } 
      } 
}

从效果上讲过滤查询和检索查询能做一样的效果。区别在于过滤查询不评分,结果能缓存,检索查询要评分,结果不缓存。 一般是不会直接使用过滤查询,都是在检索了一定数据的基础上再使用。
示例如下:

# 查询手机的价格在1900~2800之间的
GET /product/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "title": {
              "value": "手机"
            }
          }
        }
      ],
       "filter": {
          "range": {
            "price": {
              "gte": 1900,
              "lte": 2800
            }
          }
      }
    }
  }
}

9、分组查询

参数格式:

GET /索引/类型/_search 
{ 
	"size": 0, 
	"aggs": { 
		自定义分组字段: {
			"terms": { 
				"field": 分组字段, 
				"order": {自定义统计字段:排序规则}, 
				"size": 10 //默认显示10组 
				},
				"aggs": { //分组后的统计查询,相当于MySQL分组函数查询 
					自定义统计字段: { 分组运算: { "field": 统计字段 } 
					} 
				} 
		} 
	} 
}

分组运算:avg / sum / min / max / value_count / stats(执行以上所有功能的)
注意:这里是size=0其目的是为了不要显示hit内容,专注点放在观察分组上。