回顾昨日学习:

倒排索引:

  1. 1、磁盘/索引库文件夹 包含:Term Dictionary Posting List
  2. 倒排索引: 先找磁盘对应的id,再找文档,还缓冲到内存当中
  3. 2duo

ik分词器:

ik_smart; 粗粒度     ik_max_word;   细切分

今日学习知识:上午

今日讲的是最核心的内容:搜索 !!!!**

明日的前置课里一定要做好笔记!!!! 面试时有用

DSL 查询语法

Query基本语法:

// 查询所有
GET hotel/_search      //--查询的库名: hotel
{
    "query": {
        "match_all":{   //-- 查询类型:match_all   查询全部
        }
    }
}

全文检索查询:特重要!!

例子:
GET hotel/_search      
{
    "query": {
        "match": {  
             "name": "上海如家"//-- 查询类型:一个字段查询
        }
    },
        "size": 50       //-- 返回属性50条
}

GET hotel/_search      
{
    "query": {
        "multi_match": {  
             "query": "TEXT",
              "fields": ["上海如家","郁金路"] //-- 查询类型:多字段查询   不选择用这个 
        }
    },
        "size": 50       //-- 返回属性50条
}

GET hotel/_search      
{
    "query": {
        "match": {
            "all": "上海如家 "      //-- 多字段查询,只不过有看不见的内部封装  选择用这个
        }
    },
    "size":50
}

精准查询:term词条、range范围

GET hotel/_search      
{
    "query": {
        "term": {
            "price": 1679     //--精准匹配:1679价格的酒店
        }
    }
}                            //--term: 一般搜索keyword类型、数值类型、布尔类型、日期类型字段

GET hotel/_search      
{
    "query": {
        "range": {                   //--range范围匹配价格在500~1000之间
            "price": {
                "gte":  500,       
                 "lt": 1000
            }
        }
    },
    "size": 50
}        //-- range查询: 根据数值、日期范围查询

地理坐标查询:重点!

GET hotel/_search      
{
    "query": {
        "geo_distance": {
            "distance": "15km",   //--距离15km内的酒店
            "location":         //-- 地理位置
        }
    }

项目: 实物场景时,思路要清晰 总结好!!!

复合查询:

1、  fuction score: 算分函数查询    例:文档排名、百度竞价
2、  match: 相关性算分  // ES默认

Function Score Query: 重要 !!

//---  Function Score Query 定义的三要素是什么?? 思路要清晰:写分词代码前先考虑这三个条件再写
1、过滤条件:那些文档要加分
2、算分算法:如何计算function score
3、加权方式:function score 与 query score 如何运算
//-- 简单的分词查询
GET hotel/_search
{
    "query":{
        "match":{
            "name": "上海"
        }
    }
}
//-------------------老师特别讲解、分析 需看----------------------
GET hotel/_search
{
    "query":{        //-- 算法函数查询类型
        "function_score":{
            "query": {     //-- 原始查询条件
        "match":{
            "name": "上海"
        }
    },
            "functions":[    //-- 算分函数
                {           //-- 文档筛选条件
                    "filter":{
                        "term": {
                            "brand": "如家"  //-- 找到品牌如家的
                        }
                    },
                        "weight":2          //-- 给如家整体得分+2分    动态影响
                }
            ],
                "boost_mode"     //-- 加权模式: 如何 计算得分
       }
}

复合查询 Boolean Query:肯定重要!!!!

//--  bool查询有几种逻辑关系?  重中之重啊!!!!
1、must:     必须匹配的条件 与
2、must_not:  必须不匹配条件   不参与打分
3、should:   选择性匹配的条件  或
4、filter:   必须匹配的条件
条件1、2、3  数组里可以写多个条件
    //    must = 计算相似度得分    filter = 精准查询   score:在must中的条件会参与相似度得分计算
GET hotel/_search
{
    "query":{ 
        "bool": {
            "must": [                 //计分
                {
                    "match": {
                        "name": "如家"    // 第一个条件
                    }
                }
            ],
                "must_not":[ //-- 排除
                    {
                        "range": {
                            "price":{
                                "gt": 400  //第二个条件  价格不能高于:400
                            }
                        }
                    }
                ],
                "filter": [
                    {
                        "geo_distance":{
                            "distance": "10km",   //第三个必须满足的条件  地理坐标10km内满足条件
                            "location": "31.21,121.5"
                        }
                    }
                ]
        }
    }
}

// ---  例子 搜索  要不品牌希尔顿  要不价格小于500元  的50条数据
GET hotel/_search
{
    "query": {
        "bool":{
            "should":[
                {
                    "term":{
                        "brand":{
                            "value": "希尔顿"
                        }
                    }
                },
                {
                    "range": {
                        "price": {
                            "lt": 500 
                        }
                    }
                }
            ]
        }
    }
    "size": 50
}

//-- 例子
GET hotel/_search
{
    "query": {
        "bool": {
            "must"[
                {
                    "match": {
                        "name":"外滩"
                    }
                }
            ],
            "filter": [
                {
                    "range": {
                        "price": {
                            "gte": 350,
                            "lte": 1500
                        }
                    }
                }
            ],
            "must_not": [
                {
                    "term": {
                        "brand": {
                            "value":"r如家"
                        }
                    }
                }
            ]
        }
    }

}

搜索结果处理:

一、排序

分词字段不能排序,ES支持“结果排序”,默认相关算分(_score)排序
升序降序 :"order": "asc"  、、 "order": "desc"

二、分页

GET hotel/_search
{
    "query": {
        "macth_all":{}
    },
    "from": 6,    //--从第6条开始,往后搜3题
    "size":3,
    "sort":[
        {

        }
    ]
}
//--- 小面试加分问题--- 深度分页问题:From+size值 不能大于1万 ES是搭载集群的,会搭载合并,性能有很大开小
     针对深度分页:after search   不支持跳页、、但支持无线翻页
         from + size

今日学习知识:下午

搜索结果处理

高亮:

三要素:那个字段高亮、前置标签、后置标签  
          搜索那个字段才可以对那个字段做高亮
                  "require_field_match": "false"   加上这句话就可以  条件字段和搜索条件要一致了
    字段不一致要设置requireFieldMatch //不做搜索条件字段检查
  macth:全文检索、分词查询    term:不分词、精准词条查询  品牌、价格、分类
        range:范围查询 lt小于   gt   lte大于等于  gte
    geo_distance:坐标点、依次为半径查询
    1、function_score: 算分查询
        query:原始查询
        function:
        filter:给文档分值
        weight:10  最新得分    
        boost_mode: 相乘
    2、bool布尔查询  作用:组合其他多个基础条件
        must[]  :会参与计算文档的得分   里面条件都得满足
        must_not:  必须不满足
        should:   满足一个条件就行
        filter:  过滤、都是满足
        es要求from_size的值小于1W个,因为要搭集群,耽误性能
            怎么解决:使用search after 根据文档   14:50之前
query下面还可以做分页
    "from": 0  分页的开始位置
     "size": 20   期望获取的文档总数
//---- 写代码 语法规则
// -- 1、做什么样得到事情,创建对应的请求对象
     SearchRequest  请求对象
                            QueryBuilders.matchQuery();  //--ider工具类QueryBuilders
                                         termQuery();
         请求对象.source().query()
                           .from()  .size()
                            .sort()
                            .highlight()
// -- 2、调用客户端执行对应的请求
     SearchResponse    client.search(request) 
// -- 3、解析响应结果  
      SearchResponse 
         response.getHits()
                .totalValue()
                     getHits        得到文档列表,还要遍历
语法的基本结构:::

//1、创建请求
//1、1 构建条件   重点写
//2、执行请求     重点写
//3、解析结果

//得到文档列表 
//遍历文档列表

//输出文档内容    封装起来

一定要写好总结,重中之重!!!!!以后可以循环复用

实战旅游案例

location:地理坐标

距离排序

            //--  --按照地理坐标排序、定位排序、es轻松实现 ---   判断location是否有值  如果有值按照距离排序
            String location = params.getLocation();  //-- location的值在请求参数params里面获取
            if (StringUtils.isNotBlank(location)) {   //--判断不为空 做个排序
                source.sort(     //--geoDistanceSort 距离排序  fieldName:当前用来存储坐标点的字段  GeoPoint前端传过来的坐标点
                        SortBuilders.geoDistanceSort("location", new GeoPoint(location))
                .order(SortOrder.ASC)  //距离升序排序
                .unit(DistanceUnit.KILOMETERS));  //距离单位:km
            }
          //----获取排序距离 -- -- -- -- - 如果有排序字段,获取排序字段中距离的值,按照距离排序时,就知道每个酒店离的多远了
                if (StringUtils.isNotBlank(location)) {
                    Object[] sortValues = hit.getSortValues();//数组 可能有多个字段
                    if (sortValues!=null && sortValues.length>0){
                        hotelDoc.setDistance(sortValues[0]);  //--设置到距离字段上
                    }
                }

广告算分排序··广告置顶、竞价排名·

  //算分函数条件 --广告头条--谁排序第一..广告置顶、竞价排名----- ---
        FunctionScoreQueryBuilder functionScoreQueryBuilder =
                QueryBuilders.functionScoreQuery(
                        //--原始的查询条件
                        boolQuery,
                        //算分函数 数组
                        new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
                                //算分函数
                                new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                                        //筛选条件(那些文档需要重新计算得分)
                                        QueryBuilders.termQuery("isAD",true),
                                       //计算得分的方法  weight直接给一个常量分值
                                        ScoreFunctionBuilders.weightFactorFunction(10)
                                )
                        }
                        //加权模式:(算分 和 原始得分 如何计算)  默认相乘
                ).boostMode(CombineFunction.MULTIPLY);
        source.query(boolQuery);//--把算分条件装到query里面
    }
}

组合查询 — function score

function score 查询可以控制文档的相关性算分
//-- -- 更改酒店排名、写法
FunctionScoreQueryBuilder functionScoreQueryBuilder =
    QueryBuilders.functionScoreQuery(
//原始的查询条件
    boolQuery,
    //算分函数 数组
    new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
        //算分方法
        new FunctionScoreQueryBuilder.FilterFunctionBuilder (
        //筛选条件 (那些文档需要重新计算得分)
            QueryBuiders.terQuery("isAD",ture),
            //计算得分的方法 weight直接给一个常量分值
            ScoreFunctionBuilders.weightFactorFunction(10)
        )
    }
)

17:30 后面要再听一遍!!!