ElasticSearch从入门到精通

目录

一.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基本介绍

1.ElasticSearch简介

        Elasticsearch是实时的分布式搜索分析引擎,内部使用Lucene做索引与搜索

2.Elasticsearch特点

(1)准实时性:新增到 ES 中的数据在1秒后就可以被检索到,这种新增数据对搜索的可见性称为“准实时搜索”
(2)分布式:意味着可以动态调整集群规模,弹性扩容
(3)集群规模:可以扩展到上百台服务器,处理PB级结构化或非结构化数据
(4)各节点组成对等的网络结构,某些节点出现故障时会自动分配其他节点代替其进行工作

3.Elasticsearch中的基本概念

(1)索引(Index)
        相比传统的关系型数据库,索引相当于SQL中的一个【数据库】
(2)类型(Type)
        一个索引内部可以定义一个或多个类型, 在传统关系数据库来说, 类型相当于【表】的概念。
        注意:ES7之后Type被舍弃,只有Index(等同于数据库+表定义)和Document(文档,行记录)。
(3)文档(Document)
        采用JSON格式表示。相当于传统数据库【行】概念。

ElasticSearch从入门到精通_第1张图片

4.倒排索引

而ElasticSearch为了提升查询效率,采用反向思维方式,根据value找key。这就是倒排索引。

ElasticSearch从入门到精通_第2张图片

 二.ElasticSearch查询语法

1.基础查询

(1)查询所有酒店信息match_all

GET hotel/_search
{
  "query": {
    "match_all": {}
  }
}

(2)分页查询酒店列表from,size

GET hotel/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,
  "size": 5
}

(3)精确搜索term(相当于=),terms(相当于in)

        案例1:term 展示出"万豪"品牌下的所有酒店信息

GET hotel/_search
{
  "query": {
    "term": {
      "brand": "万豪"
    }
  }
}

        案例2:terms 展示出"万豪"和“如家”品牌下的所有酒店信息

GET hotel/_search
{
  "query": {
    "terms": {
      "brand": ["万豪","如家"]
    }
  }
}

(4)分词搜索:酒店名称分词查询match(单字段)multi_match(多字段)

//单字段
GET hotel/_search
{
    "query": {
        "match": {
            "name": "北京市东城区瑞麟湾酒店"
        }
    }
}

//多字段
GET hotel/_search
{
    "query": {
        "match": {
            "query": "北京市东城区瑞麟湾酒店",
            "fields": ["name","title"]
        }
    }
}

(5)模糊搜索:酒店品牌模糊搜索wildcard

//wildcard:不会对查询条件进行分词。还可以使用通配符 ?(任意单个字符) 和  * (0个或多个字符)
GET hotel/_search
{
    "query": {
        "wildcard": {
            "brand": "万*"
        }
    }
}

(6)多字段搜索query_string

//可以指定多个域、会对搜索条件分词、将分词后的搜索条件与term匹配、取结果并集OR、交集AND
GET hotel/_search
{
    "query": {
        "query_string": {
            "fields": ["name", "address", "area", "synopsis"],
            "query": "spa OR 商务"
        }
    }
}

(7)排序sort

//根据salesVolume升序排
GET hotel/_search
{
    "sort": {
        "salesVolume": {
            "order": "asc"
        }
    }
}

(8)范围搜索range

//range: gt 大于、gte 大于等于、 lt 小于、lte 小于等于

GET hotel/_search
{
    "query": {
        "range": {
            "price": {
                "gte": 600,
                "lt": 1600
            }
        }
    }
}

(9)自动纠错搜索

//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": "北经市"
        }
      }
    }
}

(10)高亮搜索

//highlight:如需将搜索条件以高亮形式展示,则需要在查询时,设置需要对哪一个域以何种样式进行展示,fields 设置要对哪个域高亮、pre_tags 设置高亮样式前缀、post_tags 设置高亮样式后缀。
GET hotel/_search
{
    "query": {
       "term": {
           "name": "新乐"
       }
    },
    "highlight": {
        "fields": {
            "name": {
                "pre_tags": "",
                "post_tags": ""
            }
        }
    }
}

(11)指定查询哪些字段 _source

//展示那么和price字段
GET hotel/_search
{  
 "query": {
    "term": {
      "brand": "万豪"
    }
  },
 "_source": ["name","price"],
}


//有以下连个可选项
includes:来指定想要显示的字段
excludes:来指定不想要显示的字段
GET hotel/_search
{
    "_source": {
        "includes":["title","price"]
    },
    "query": {
        "term": {
            "price": 2699
        }
    }
}

2.bool查询

        must(and)条件必须成立
        must_not (not)条件必须不成立
        should(or)条件可以成立
        filter (and)条件过滤,必须成立,但是不予评分

(1)must

        must单独使用 品牌必须是万豪,地区必须是北京市

GET hotel/_search
{
    "query": {
        "bool": {
            "must": [
                {
                   "term": {
                        "brand": "万豪"
                    }
                },{
                    "term": {
                        "area": "北京市"
                    }
                }
            ]
        }
    }
}

(2)filter

GET hotel/_search
{
    "query": {
        "bool": {
            "filter": [
                {
                    "term": {
                         "brand": "万豪"
                    }
                },{
                    "term": {
                        "area": "北京市"
                    }
                }
            ]
        }
    }
}

(3)must和filter组合

## must和filter组合使用 品牌为万豪下的,地区为北京市、价格范围在500和2000之间的酒店
GET hotel/_search
{
    "query": {
        "bool": {
            "must": [
                {
                   "term": {
                        "brand": "万豪"
                    }
                }
            ],
            "filter": [
                {
                    "term": {
                        "area": "北京市"
                    }
                },{
                    "range": {
                        "price": {
                            "gte": 500,
                            "lte": 2000
                        }
                    }
                }
            ]
        }
    }
}

3.聚合查询

ES中的聚合搜索分为两类:
        指标聚合:如max、min、sum等。作用等同MySQL中相关聚合函数
        桶聚合:用于数据分组,作用等同于MySQL中的group by

(1)指标聚合aggs

        统计品牌为万豪下最贵酒店价格

GET hotel/_search
{
    "query": {
       "term": {
           "brand": "万豪"
       }
    },
    "aggs": {
        "my_max_price": {
            "max": {
                "field": "price"
            }
        }
    }
}

(2)桶聚合aggs

        案例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"
          }
        }
      }
    }
  }
}

4.优化多字段查询

        搜索时,对于每条搜索结果ES都会对其按照匹配度进行打分,分数越高,在结果中排名越靠前。
        在ES中提供了以下两种设置权重的方式:
        (1)索引设置:创建索引时配置权重,该方式应用较少,因为一旦需求发生改变,则需要重新创建索引。
        (2)查询设置:在查询时,根据需求灵活的配置权重,该方式使用最多。

(1)提升字段查询得分

        将name字段查询比重提升10倍

GET hotel/_search
{
  "explain": true, 
  "query":{
    "multi_match":{
      "query": "北京金龙",
      "fields": ["name^10", "address"]
    }
  }
}

(2)综合提升字段查询得分

        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,这样搜索的关联性就提升上去了, 更为合理。

(3)自定义评分

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模糊查询

你可能感兴趣的:(java,数据库,中间件,elasticsearch,java)