回顾昨日学习:
倒排索引:
1、磁盘/索引库文件夹 包含:Term Dictionary 、 Posting List
倒排索引: 先找磁盘对应的id,再找文档,还缓冲到内存当中
2、duo
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)
)
}
)