ES学习笔记003-基本的查询方式

1、query string search

GET /ecommerce/product/_search

GET /ecommerce/product/_search?q=name:yagao&sort=price:desc

ES的搜索提供的是 restful 风格,所以可以用 http 的方式来请求,上面第二条语句代表搜索参数q为name=yagao,按照价格 price 降序排列。
针对查询结果如下:
在这里插入图片描述

  • took:耗费了几毫秒 timed_out:是否超时,这里是没有
    _shards:数据拆成了多少个分片,所以对于搜索请求,会打到所有的primary shard(或者是它的某个replica shard也可以) hits.total:查询结果的数量,4个document
    hits.max_score:score的含义,就是document对于一个search的相关度的匹配分数,越相关,就越匹配,分数也高
    hits.hits:包含了匹配搜索的document的详细数据

2、query DSL

DSL:Domain Specified Language,特定领域的语言
http request body:请求体,可以用json的格式来构建查询语法,比较方便,可以构建各种复杂的语法,比query string search肯定强大多了

#查询所有数据
GET /ecommerce/product/_search
{
  "query": {
    "match_all": {}
  }
}
#查询名字包含 heiren 的数据
GET /ecommerce/product/_search
{
  "query":{
    "match": {
      "name": "heiren"
    }
  }
}
#查询数据同时按照价格排序,注意排序 sort 的参数是数组
GET /ecommerce/product/_search
{
  "query": {
    "match": {
      "name": "yagao"
    }
  },
  "sort": [
    {
      "price":{
        "order": "desc"
      }
    }
  ]
}
#分页查询指定数据,且,指定需要查询的列,比较适合生产环境,读取指定列数据,降低IO
GET ecommerce/product/_search
{
  "query":{"match_all":{}},
  "from": 1,
  "size":1,
  "_source":["desc","price"]
}

3、query filter

#查询的数据满足特定的filter条件
#名称包含牙膏,且,价格大于等44的数据
GET /ecommerce/product/_search
{
  "query":{
    "bool":{
      "must":{
        "match":{
          "tags":"meibai"
        }
      },
      "filter":{
        "range":{
          "price":{"gte":44}
        }
      }
    }
  }
}

4、full-text search

#查询名称包含 gaolujie或者 yagao 的数据
GET /ecommerce/product/_search
{
  "query":{
    "match": {
      "name":"gaolujie yagao"
    }
  },
  "_source":["name"]
}

ES 中的数据,name 会被拆解进行倒排索引,排序结果如下:

词名数据ID值
yagao1,2,3,4
gaolujie1
zhonghua3
jiajieshi2
heiren4

同时在查询的时候,name 也会被拆解为 gaolujie 和 yagao
然后在查询的时候,就在分词表中匹配,匹配出这些词语,然后拿到对应的数据ID,返回,在返回前还会根据数据匹配度进行排序,匹配度越高分值越高,靠近前面
在这里插入图片描述

5、phrase search(短语搜索)

跟全文检索相对应,相反,全文检索会将输入的搜索串拆解开来,去倒排索引里面去一一匹配,只要能匹配上任意一个拆解后的单词,就可以作为结果返回
phrase search,要求输入的搜索串,必须在指定的字段文本中,完全包含一模一样的,才可以算匹配,才能作为结果返回

GET /ecommerce/product/_search
{
  "query":{
    "match_phrase": {
      "producer": "gaolujie productr"
    }
  },
    "_source":["name"]
}

查询结果只有一条数据,语法类似于SQL中的: like ‘%query char%’
在这里插入图片描述

6、highlight search(高亮搜索结果)

其实不算是一种查询方式吧,只是把对搜索的结果进行高亮处理,结果为html标签


GET /ecommerce/product/_search
{
  "query":{
    "match":{
      "producer": "productr"
    }
  },
  "_source":["name"],
 "highlight": {
    "fields" : {
        "producer" : {}
    }
  }
}

在这里插入图片描述

7、聚合查询

a、简单的group by 操作,统计每一种类型牙膏数量

#按照 tags 来进行group 
GET /ecommerce/product/_search
{ 
  "size":0,
  "aggs": {
    "group_by_tags": {
      "terms": {
        "field": "tags",
        "size": 10
      }
    }
  }
}

执行后,会抛出如下错误,正常的,这个时候按照错误提示需要更改字段field的 fielddata 为true
在这里插入图片描述

#设置字段的fielddata为true, 注意在api 后面没有添加 索引的 type
PUT /ecommerce/_mapping
{
    "properties":{
      "tags":{
        "fielddata":true,
        "type":"text"
      }
    }  
}

设置完上面的属性后,就可以再次运行下面的语句,得到想要的结果

GET /ecommerce/product/_search
{ 
  "size":0,
  "aggs": {
    "group_by_tags": {
      "terms": {
        "field": "tags",
        "size": 10
      }
    }
  }
}
  • size:0 就是不显示被检索的数据,否则会把所有搜索到的数据都现实出来
  • aggs: 代表聚合操作
  • group_by_tags:我们自己给当前聚合操作起的名字
  • terms:代表用哪一种方式来进行聚合操作
  • field:用哪一个字段来聚合
  • size:10 聚合结果现实的个数,类似于SQL 总的 select top 10 id.count(1) fro tb group id;

扩展一下: 统计满足要求的每一个tag下牙膏数量

GET /ecommerce/product/_search
{
  "size": 0, 
  "query": {
    "match": {
      "name": "yagao"
    }
  },
  "aggs":{
    "group_by_tags":{
      "terms": {
        "field": "tags",
        "size": 10
      }
    }
  }
}

b、先分组,然后在计算分组下的平均值

GET /ecommerce/product/_search
{
  "size": 0,
  "aggs":{
    "group_by_avg":{
      "terms": {
        "field": "tags"
      },
      "aggs": {
        "avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    }
  }
}

因为是先分组,后求平均值,所以在 terms 同一个分组查询中,类似于 SQL 中,group by 后面的 avg 道理,结果也如下所示
在这里插入图片描述

c、分组后求平均值,切按照平均值降序排列

GET /ecommerce/product/_search
{
  "size": 0,
  "aggs": {
    "group_by_avg": {
      "terms": {
        "field": "tags",
        "size": 10,
        "order": {
          "avg_price": "asc"
        }
      },
      "aggs":{
        "avg_price":{
          "avg":{
            "field":"price"
          }
        }
      }
    }
  }
}

先分组,后求平均值,在根据平均值排序,平均值是针对分组的,所以,排序放在分组 terms 里面,排序的时候,是按照平均值排序,所以 order 后面跟的是求平均值的 _term 名字
类比SQL:先 group by 在 avg, 然后在 order by

d、先按照价格指定去间范围,然后在分组求平均值

GET /ecommerce/product/_search
{
  "size": 0,
  "aggs":{
    "group_by_rang":{
      "range": {
        "field": "price",
        "ranges": [
          {
            "from": 30,
            "to": 40
          },
          {
            "from": 41,
            "to":100
          }
        ]
      },
      "aggs": {
        "grpy_by_tag": {
          "terms": {
            "field": "tags",
            "size": 10
          },
          "aggs":{
            "avg_price":{
              "avg": {
                "field": "price"
              }
            }
          }
        }
      }
    }
  }
}

注意:分区间的时候,默认的 from 是包含,to 是不包含的
另:上面分组和分区间是平级的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值