目录
一.ElasticSearch基本介绍
1.ElasticSearch简介
2.Elasticsearch特点
3.Elasticsearch中的基本概念
4.倒排索引
二.ElasticSearch查询语法
1.基础查询
(1)查询所有酒店信息match_all
(2)分页查询酒店列表from,size
(3)精确搜索term(相当于=),terms(相当于in)
(4)分词搜索:酒店名称分词查询match(单字段)multi_match(多字段)
(5)模糊搜索:酒店品牌模糊搜索wildcard
(6)多字段搜索query_string
(7)排序sort
(8)范围搜索range
(9)自动纠错搜索
(10)高亮搜索
(11)指定查询哪些字段 _source
2.bool查询
(1)must
(2)filter
(3)must和filter组合
3.聚合查询
(1)指标聚合aggs
(2)桶聚合aggs
4.优化多字段查询
(1)提升字段查询得分
(2)综合提升字段查询得分
(3)自定义评分
Elasticsearch是实时的分布式搜索分析引擎,内部使用Lucene做索引与搜索
(1)准实时性:新增到 ES 中的数据在1秒后就可以被检索到,这种新增数据对搜索的可见性称为“准实时搜索”
(2)分布式:意味着可以动态调整集群规模,弹性扩容
(3)集群规模:可以扩展到上百台服务器,处理PB级结构化或非结构化数据
(4)各节点组成对等的网络结构,某些节点出现故障时会自动分配其他节点代替其进行工作
(1)索引(Index)
相比传统的关系型数据库,索引相当于SQL中的一个【数据库】
(2)类型(Type)
一个索引内部可以定义一个或多个类型, 在传统关系数据库来说, 类型相当于【表】的概念。
注意:ES7之后Type被舍弃,只有Index(等同于数据库+表定义)和Document(文档,行记录)。
(3)文档(Document)
采用JSON格式表示。相当于传统数据库【行】概念。
而ElasticSearch为了提升查询效率,采用反向思维方式,根据value找key。这就是倒排索引。
GET hotel/_search
{
"query": {
"match_all": {}
}
}
GET hotel/_search
{
"query": {
"match_all": {}
},
"from": 0,
"size": 5
}
案例1:term 展示出"万豪"品牌下的所有酒店信息
GET hotel/_search
{
"query": {
"term": {
"brand": "万豪"
}
}
}
案例2:terms 展示出"万豪"和“如家”品牌下的所有酒店信息
GET hotel/_search
{
"query": {
"terms": {
"brand": ["万豪","如家"]
}
}
}
//单字段
GET hotel/_search
{
"query": {
"match": {
"name": "北京市东城区瑞麟湾酒店"
}
}
}
//多字段
GET hotel/_search
{
"query": {
"match": {
"query": "北京市东城区瑞麟湾酒店",
"fields": ["name","title"]
}
}
}
//wildcard:不会对查询条件进行分词。还可以使用通配符 ?(任意单个字符) 和 * (0个或多个字符)
GET hotel/_search
{
"query": {
"wildcard": {
"brand": "万*"
}
}
}
//可以指定多个域、会对搜索条件分词、将分词后的搜索条件与term匹配、取结果并集OR、交集AND
GET hotel/_search
{
"query": {
"query_string": {
"fields": ["name", "address", "area", "synopsis"],
"query": "spa OR 商务"
}
}
}
//根据salesVolume升序排
GET hotel/_search
{
"sort": {
"salesVolume": {
"order": "asc"
}
}
}
//range: gt 大于、gte 大于等于、 lt 小于、lte 小于等于
GET hotel/_search
{
"query": {
"range": {
"price": {
"gte": 600,
"lt": 1600
}
}
}
}
//fuzzyQuery:自动尝试将条件纠错,并和词条匹配、fuzziness 允许对几个字进行纠错、prefix_length //设置前几个字符不允许编辑
//在未经处理的情况下,一旦条件存在错别字,找不到term,则无法查询到结果
## 正常搜索
GET hotel/_search
{
"query": {
"term": {
"area": "北京市"
}
}
}
## 错别字 经
GET hotel/_search
{
"query": {
"term": {
"area": "北经市"
}
}
}
## 自动纠错搜索 经
GET hotel/_search
{
"query": {
"fuzzy": {
"area": {
"fuzziness": 1,
"prefix_length": 1,
"value": "北经市"
}
}
}
}
//highlight:如需将搜索条件以高亮形式展示,则需要在查询时,设置需要对哪一个域以何种样式进行展示,fields 设置要对哪个域高亮、pre_tags 设置高亮样式前缀、post_tags 设置高亮样式后缀。
GET hotel/_search
{
"query": {
"term": {
"name": "新乐"
}
},
"highlight": {
"fields": {
"name": {
"pre_tags": "",
"post_tags": ""
}
}
}
}
//展示那么和price字段
GET hotel/_search
{
"query": {
"term": {
"brand": "万豪"
}
},
"_source": ["name","price"],
}
//有以下连个可选项
includes:来指定想要显示的字段
excludes:来指定不想要显示的字段
GET hotel/_search
{
"_source": {
"includes":["title","price"]
},
"query": {
"term": {
"price": 2699
}
}
}
must(and)条件必须成立
must_not (not)条件必须不成立
should(or)条件可以成立
filter (and)条件过滤,必须成立,但是不予评分
must单独使用 品牌必须是万豪,地区必须是北京市
GET hotel/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"brand": "万豪"
}
},{
"term": {
"area": "北京市"
}
}
]
}
}
}
GET hotel/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"brand": "万豪"
}
},{
"term": {
"area": "北京市"
}
}
]
}
}
}
## must和filter组合使用 品牌为万豪下的,地区为北京市、价格范围在500和2000之间的酒店
GET hotel/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"brand": "万豪"
}
}
],
"filter": [
{
"term": {
"area": "北京市"
}
},{
"range": {
"price": {
"gte": 500,
"lte": 2000
}
}
}
]
}
}
}
ES中的聚合搜索分为两类:
指标聚合:如max、min、sum等。作用等同MySQL中相关聚合函数
桶聚合:用于数据分组,作用等同于MySQL中的group by
统计品牌为万豪下最贵酒店价格
GET hotel/_search
{
"query": {
"term": {
"brand": "万豪"
}
},
"aggs": {
"my_max_price": {
"max": {
"field": "price"
}
}
}
}
案例1:统计品牌为万豪下有哪些星级
GET hotel/_search
{
"query": {
"term": {
"brand": "万豪"
}
},
"aggs": {
"my_group": {
"terms": {
"field": "specs",
"size": 5
}
}
}
}
案例2:根据搜索条件对品牌分组
GET hotel/_search
{
"query": {
"query_string": {
"fields": ["name", "synopsis", "area", "address"],
"query": "三亚 OR 商务"
}
},
"aggs": {
"hotel_brand": {
"terms": {
"field": "brand",
"size": 100
}
}
}
}
案例3:统计某品牌下酒店指定时间段内的销量
GET hotel/_search
{
"query": {
"range": {
"createTime": {
"gte": "2016-01-01",
"lte": "2021-01-01"
}
}
},
"aggs": {
"hotel_brand": {
"terms": {
"field": "brand",
"size": 100
},
"aggs": {
"sale_count": {
"sum": {
"field": "salesVolume"
}
}
}
}
}
}
搜索时,对于每条搜索结果ES都会对其按照匹配度进行打分,分数越高,在结果中排名越靠前。
在ES中提供了以下两种设置权重的方式:
(1)索引设置:创建索引时配置权重,该方式应用较少,因为一旦需求发生改变,则需要重新创建索引。
(2)查询设置:在查询时,根据需求灵活的配置权重,该方式使用最多。
将name字段查询比重提升10倍
GET hotel/_search
{
"explain": true,
"query":{
"multi_match":{
"query": "北京金龙",
"fields": ["name^10", "address"]
}
}
}
tie_breaker:将其他query的分数也考虑进去(最大值加上其他值的0.3倍)
GET hotel/_search
{
"explain": true,
"query":{
"multi_match":{
"query": "北京金龙",
"fields": ["name", "address"],
"tie_breaker": 0.3
}
}
}
使用 tie_breaker 和不使用tie_breaker ,查询出来的某一条数据的 _score 分数,会有相应的提高,例如:
name中包含关键词matched query 的得分,假设是 0.1984226
address中包含关键词matched query的得分,假设是 12.07466
添加了 tie_breaker = 0.3,那么就是这样的了, 0.1984226 * 0.3 + 12.07466 = 12.13418678
大于最高一条的得分12.07466,这样搜索的关联性就提升上去了, 更为合理。
1.创建索引时设置权重
## 查询多域展示相关结果数据
GET hotel/_search
{
"query": {
"query_string": {
"fields": ["name", "synopsis", "area", "address"],
"query": "北京市万豪spa三星"
}
}
}
## 评分扩大10倍
GET hotel/_search
{
"query": {
"query_string": {
"fields": ["name", "synopsis", "area", "address"],
"query": "北京市万豪spa三星",
"boost": 10
}
}
}
2.查询时设置权重(function_score)
## 为品牌为万豪的酒店,权重值增加50倍
GET hotel/_search
{
"query": {
"function_score": {
"query": {
"query_string": {
"fields": ["name", "synopsis", "area", "address"],
"query": "北京市万豪spa三星"
}
},
"functions": [
{
"filter": {
"term": {
"brand": "万豪"
}
},
"weight": 50
}
]
}
}
}
## 将广告酒店的权重增加100倍,使其靠前
GET hotel/_search
{
"query": {
"function_score": {
"query": {
"query_string": {
"fields": ["name", "synopsis", "area", "address"],
"query": "北京市万豪spa三星"
}
}
}
}
}
GET hotel/_search
{
"query": {
"function_score": {
"query": {
"query_string": {
"fields": ["name", "synopsis", "area", "address"],
"query": "北京市万豪spa三星"
}
},
"functions": [
{
"filter": {
"term": {
"isAd": "1"
}
},
"weight": 100
}
]
}
}
}
更多查询语法请见这篇文章:es 模糊查询_jojoRey的博客-CSDN博客_es模糊查询