基础数据

创建索引

PUT mytest
{
"mappings": {
"properties": {
"title": {
"type": "text",
"fields": {
"keyword": {
"type": "text",
"analyzer": "standard"
}
}
},
"tag": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"content": {
"type": "text",
"fields": {
"std": {
"type": "text",
"analyzer": "standard"
},
"cn": {
"type": "text",
"analyzer": "ik_smart"
}
}
},
"score": {
"type": "byte"
},
"time":{
"type": "date"
}
}
},
"settings": {
"index": {
"number_of_shards": "1",
"number_of_replicas": "0"
}
}
}
POST mytest/_doc/001
{
"title": "好评不错",
"tag": "精彩",
"content": "这里必须有一些内容,来表示这个评论是好评",
"score": 90,
"time": 1596441469000
}
POST mytest/_doc/002
{
"title": "一般评价",
"tag": "普通",
"content": "这里可以有一些内容,来表示这个评论是一般的",
"score": 80,
"time": 1596355069000
}
POST mytest/_doc/003
{
"title": "很差的评价",
"tag": "TCL",
"content": "这里没有一些内容,来表示这个评论是OK的",
"score": 20,
"time": 1596268669000
}
POST mytest/_doc/004
{
"title": "超级好评",
"tag": "精彩",
"content": "这里必须有一些内容,来表示这个评论是好评好评好评好评好评好评好评好评好评好评好评好评好评",
"score": 2,
"time": 1596441469000
}

短语匹配

  1. 不指定匹配的 fields 时候, 是否会查找全部字段?

不指定 fields 搜索

POST mytest/_search
{
"explain": true,
"query": {
"match": {
"content": "好评"
}
}
}

搜索结果为 3 条。在 explain 的结果中可以看到, details 评分统计了两个字段的结果

为了验证上面结果, 在指定域搜索只能看到一条结果

POST mytest/_search
{
"query": {
"match": {
"content.cn": "好评"
}
}
}
  1. match 和 match_phrase 区别
POST mytest/_search
{
"explain": false,
"query": {
"match": {
"content.cn":{
"query": "这里可以有一些内容",
"analyzer": "ik_smart"
}
}
}
}

"这里可以有一些内容" 通过 ik_smart 分词器被分成了 [这里 可以 有 一些 内容]

五个词都放入到 es 中搜索, 所以这里可以搜索出三个结果

可以通过比例限制匹配的结果, 限制到 90% 后, 只能匹配到 1 条结果

POST mytest/_search
{
"query": {
"match": {
"content.cn":{
"query": "这里可以有一些内容",
"analyzer": "ik_smart",
"minimum_should_match": "90%"
}
}
}
}

match_phrase 只能匹配到 1 条结果, 如果把文本换成 "这里可以有内容一些", 就不能匹配到内容了

这时需要使用 slop 完成近似匹配, 允许有顺序的差异. 同时, 使用 match 匹配的时候, 词的顺序不影响结果得分

POST mytest/_search
{
"query": {
"match_phrase": {
"content.cn":{
"query": "这里可以有一些内容",
"analyzer": "ik_smart",
"slop": 0
}
}
}
}
  1. 精确搜索的时候, 可以使用默认分词器, 以达到精确的目的

    在搜索中输入 "以有一些内容" 不完整的内容, 也可以搜索到精确的结果

    修改为 match 可以
POST mytest/_search
{
"query": {
"match_phrase": {
"content.std":{
"query": "以有一些内容",
"analyzer": "standard"
}
}
}
}

自定义打分

打分公式

score(q,d) = queryNorm(q)            //归一化因子
·coord(q,d) //协调因子
·∑( tf(t in d) //词频
·idf(t)² //逆向文档频率
·t.getBoost() //权重
·norm(t,d) //字段长度归一值
)(t in q)

queryNorm 查询归化因子: 会被应用到每个文档, 不能被更改, 总而言之, 可以被忽略

coord 协调因子: 可以为那些查询词包含度高的文档提供奖励, 文档里出现的查询词越多, 它越有机会成为好的匹配结果

协调因子将评分与文档里匹配词的数量相乘,然后除以查询里所有词的数量,如果使用协调因子,评分会变成:

文档里有 fox → 评分: 1.5 * 1 / 3 = 0.5

文档里有 quick fox → 评分: 3.0 * 2 / 3 = 2.0

文档里有 quick brown fox → 评分: 4.5 * 3 / 3 = 4.5

协调因子能使包含所有三个词的文档比只包含两个词的文档评分要高出很多

  1. 提升查询权重
POST mytest/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"title": {"query": "好评", "boost": 10}
}
},
{"match": {"content": "有一些内容"}
}
]
}
}
}
  1. 结合 function_score 查询 与 field_value_factor 查询可以实现按照文档的字段来影响文档评分
POST mytest/_search
{
"query": {
"function_score": {
"query": {
"multi_match": {"query": "好评","fields": ["title", "content"]}
},
"functions": [
{"field_value_factor": {"field": "score"}}
]
}
}
}

new_score = old_score * number_of_votes

这样会导致 votes 为 0 的文档评分为 0,而且 votes 值过大会掩盖掉全文评分

  1. 一般会使用 modifier 参数来平滑 votes 的值
POST mytest/_search
{
"query": {
"function_score": {
"query": {
"multi_match": {"query": "好评","fields": ["title", "content"]}
},
"functions": [
{"field_value_factor": {"field": "score", "modifier": "log1p"}}
]
}
}
}

应用值为 log1p 的 modifier 后的评分计算公式:

new_score = old_score * log(1 + number_of_votes)

modifier 的可以为: none ,log ,log1p ,log2p ,ln ,ln1p ,ln2p ,square ,sqrt ,reciprocal

  1. factor 可以通过将 votes 字段与 factor 的积来调节受欢迎程度效果的高低
"functions": [
{"field_value_factor": {"field": "score", "modifier": "ln1p", "factor": 10}}
]

添加了 factor 会使公式变成这样:

new_score = old_score * log(1 + factor * number_of_votes)

  1. 通过参数 boost_mode 来控制函数与查询评分 _score 合并后的结果,参数接受的值

    multiply: 评分 _score 与函数值的积(默认)

    sum: 评分 _score 与函数值的和

    min: 评分 _score 与函数值间的较小值

    max: 评分 _score 与函数值间的较大值

    replace: 函数值替代评分 _score
"functions":[],
"boost_mode": "sum"

之前请求的公式现在变成下面这样:

new_score = old_score + log(1 + 0.1 * number_of_votes)

  1. 可以使用 max_boost 参数限制一个函数的最大效果
"boost_mode": "sum"
"max_boost": 1.5

无论 field_value_factor 函数的结果如何,最终结果都不会大于 1.5 。

注意 max_boost 只对函数的结果进行限制,不会对最终评分 _score 产生直接影响。

  1. 评分模式 score_mode

    每个函数返回一个结果,所以需要一种将多个结果缩减到单个值的方式,然后才能将其与原始评分 _score 合并。

    评分模式 score_mode 参数正好扮演这样的角色, 它接受以下值:

multiply : 函数结果求积(默认)。

sum : 函数结果求和。

avg : 函数结果的平均值。

max : 函数结果的最大值。

min : 函数结果的最小值。

first : 使用首个函数(可以有过滤器,也可能没有)的结果作为最终结果

在本例中,我们将每个过滤器匹配结果的权重 weight 求和,并将其作为最终评分结果,所以会使用 sum 评分模式。

不与任何过滤器匹配的文档会保有其原始评分, _score 值的为 1 。

  1. 衰减函数

    这需要使用 function_score 查询提供的一组 衰减函数(decay functions)

    linear 线性函数

    exp 指数函数

    gauss 高斯函数

所有三个函数都接受如下参数:

origin:中心点 或字段可能的最佳值,落在原点 origin 上的文档评分 _score 为满分 1.0 。

scale:衰减率,即一个文档从原点 origin 下落时,评分 _score 改变的速度。(例如,每 £10 欧元或每 100 米)。

decay:从原点 origin 衰减到 scale 所得的评分 _score ,默认值为 0.5 。

offset:以原点 origin 为中心点,为其设置一个非零的偏移量 offset 覆盖一个范围,而不只是单个原点。在范围 -offset <= origin <= +offset 内的所有评分 _score 都是 1.0

      "functions": [
{
"exp": {
"time": {
"origin": "1596530751000",
"scale": "10d",
"offset": "5d",
"decay": 0.5
}
}
}
]

elasticsearch 高级搜索示例 es7.0的更多相关文章

  1. Elasticsearch高级搜索排序( 中文+拼音+首字母+简繁转换+特殊符号过滤)

    一.先摆需求: 1.中文搜索.英文搜索.中英混搜   如:"南京东路","cafe 南京东路店" 2.全拼搜索.首字母搜索.中文+全拼.中文+首字母混搜   如 ...

  2. Elasticsearch分布式搜索和数据分析引擎-ElasticStack(上)v7.14.0

    Elasticsearch概述 **本人博客网站 **IT小神 www.itxiaoshen.com Elasticsearch官网地址 https://www.elastic.co/cn/elast ...

  3. Elasticsearch(ES)的高级搜索(DSL搜索)(上篇)

    1. 概述 之前聊了一下 Elasticsearch(ES)的基本使用,今天我们聊聊 Elasticsearch(ES)的高级搜索(DSL搜索),由于DSL搜索内容比较多,因此分为两篇文章完成. 2. ...

  4. Elasticsearch(ES)的高级搜索(DSL搜索)(下篇)

    1. 概述 之前聊了Elasticsearch(ES)的高级搜索(DSL搜索)的一部分内容,今天把剩下的部分聊完. 2. 场景说明 2.1 创建索引同时创建映射 PUT  http://192.168 ...

  5. 如何使用GOOGLE高级搜索技巧

    如何使用GOOGLE高级搜索技巧 一,GOOGLE简介 Google(www.google.com)是一个搜索引擎,由两个斯坦福大学博士生Larry Page与Sergey Brin于1998年9月发 ...

  6. GOOGLE高级搜索的秘籍

    一.摘要 本文内容来源自互联网,全面的介绍Google搜索的各种功能和技巧. 二.GOOGLE简介 Google(http://www.google.com/)是一个搜索引擎,由两个斯坦福大学博士生L ...

  7. GOOGLE高级搜索技巧

    前记:  我是完整的看完了.内容有点乱啊,自己没有时间整理,先放在自己的印象笔记里了....   二,GOOGLE特色 GOOGLE支持多达132种语言,包括简体中文和繁体中文: GOOGLE网站只提 ...

  8. 使用 Google 高级搜索的一些技巧

      一,GOOGLE简介 Google(www.google.com)是一个搜索引擎,由两个斯坦福大学博士生Larry Page与Sergey Brin于1998年9月发明,Google Inc. 于 ...

  9. 65. XPages自定义控件(三)高级搜索之三

    RecordView控件的两个文件的完整代码在本文末尾给出.虽说完整,仅靠这两个文件,RecordView控件还不能正常工作,因为在这两个文件里还引用了其他自定义控件,调用了作为managed bea ...

随机推荐

  1. JavaWeb基础(day11)

    HTML HTML是超文本标记语言.HTML就 是普通的文本文件,只不过在文本中的内容如果被一些 特殊的标签进行包裹就有了特殊的含义,这些被那些标签标记文本,就成了超文本. 网页的组成 网页的组成 H ...

  2. requests接口自动化7-Multi/form-data文件上传形式的post请求:files

    Multi/form-data文件上传形式的post请求:用files传参 fiddler里请求响应内容; 代码: import requests from requests_toolbelt imp ...

  3. python面试题二:Python 基础题

    1.位和字节的关系? Byte 字节 bit 位 1Byte = 8bit 2.b.B.KB.MB.GB 的关系? 1Byte = 8bit KB 1KB=1024B MB 1MB=1024KB GB ...

  4. Python读取文件基本方法

    在日常开发过程中,经常遇到需要读取配置文件,这边就涉及到一个文本读取的方法. 这篇文章主要以Python读取文本的基础方法为本,添加读取整篇文本返回字符串,读取键值对返回字典,以及读取各个项返回列表的 ...

  5. ShaderLab-坐标转换

    观察空间就是相机的空间 投影矩阵本质就是对x.y.z分量进行不同程度的缩放(z还做了平移),结果就是视锥体近切面远切面变成正方形.视锥体的中心在(0,0). (对于正交相机,这一步已经得到了立方体) ...

  6. 在Java中使用AES加密

    本文转载https://blog.csdn.net/z69183787/article/details/82746686

  7. cropper.js 二次开发:截图并下载图片

    cropper.js 是一个基于jquery的图片截取库. 参考:https://blog.csdn.net/weixin_38023551/article/details/78792400 我的代码 ...

  8. 本周六 Apache DolphinScheduler & Doris 将联合线上 Meetup

    活动背景 2020年,大数据成为国家基建的一个重要组成,大数据在越来越多的领域展现威力.随着大数据的应用场景越来越多,大家对数据的响应速度和数据加工工作流的方便程度也提出了更高的要求.在这种背景下,相 ...

  9. 题解 洛谷 P4602 【[CTSC2018]混合果汁】

    注意到问题具有单调性,所以一个询问可以通过二分答案来解决. 对于多组询问,就采用整体二分来处理. 将果汁按\(d\)从大到小排序,二分出一个位置\(mid\),只考虑在位置\(mid\)之前的果汁,其 ...

  10. Python基础学习之环境搭建

    Python如今成为零基础编程爱好者的首选学习语言,这和Python语言自身的强大功能和简单易学是分不开的.今天我们将带领Python零基础的初学者完成入门的第一步——环境搭建.本文会先来区分几个在P ...