Elasticsearch 如何实现类主流搜索引擎广告置顶显示效果?

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 1、需求wx私信问题:Elasticsearch 如何实现类似百度广告置顶显示给定商品数据的效果?置顶显示某特定数据就是:搜索某关键词,出现关联广告置顶显示的效果。举例:百度搜索“电动汽车”,结果如下:

image.png

上面实现的本质:返回结果的第一页头1条或多条数据是服务端(如电商网站、主流搜索引擎)指定的数据,而非按照相关度评分计算得出的结果数据。


这时候,不禁要问 Elasticsearch 能实现类似功能不 ?


2、拆解实现

Elasticsearch from + size 分页实现机制的原理(大致意思):


page 1:from 0,size:10——返回第 0 到 第 9 条数据。


page 2:from 10,size:10——返回第 0 到 第 19 条数据,截取第 10 到 第 19 条数据;


page 3:from 20,size:10——返回第 0 到 第 29 条数据,截取 第 20到 第 29 条数据。


......


本质是深度分页,肯定越往后翻页响应越慢。


要实现根据固定关键词添加特定数据置顶显示的效果,探讨方案如下:


2.1 方案一:不重新分页,牺牲首页部分数据

不再做重新分页,强制将 page 1 部分数据,换成:类【广告位】置顶显示数据。


显然,会有数据丢失,导致搜索精准率下降,用户一般不会接受。


2.2 方案二:重新内存分页

将类【广告位】置顶显示数据 + 已有返回的前10页(举例:100 条数据)重新组合后,再分页。


需要内存维护一堆数据,有较大内存开销。用户期望翻页越深(比如:100页+),维护数据越大,处理越慢、延时会越明显。


2.3 方案三:其他方案

类主流搜索引擎实现的方法或者读者新的实现机制。


但,此时要想,有没有更简洁的实现呢?


Elastic 官方就没有考虑这个用户需求吗?


有的,Elasticsearch 7.4.0 新增的 pinned query 就能实现这种功能。


且听慢慢道来......


3、pinned query 介绍

pinned query 是 Elasticsearch 7.4.0 版本实现的增强检索功能。


pinned:中文翻译为“固定”。


pinned query 则可以解释为——固定某些结果首页置顶显示的检索方式。


下图更能形象的说明:绿色的 Pinned results 就是要首页置顶显示的结果。

image.png

4、 pinned query 实战实现

基础数据 Demo 如下,直接拿文章开头的截图示例模拟一下,假设 id为 1、2、3 的3条数据是需要特意置顶显示的数据。


PUT index_001

{

 "mappings": {

   "properties": {

     "title":{

       "type": "text",

       "analyzer": "ik_max_word",

       "fields": {

         "keyword":{

           "type":"keyword"

         }

       }

     }

   }

 }

}

PUT index_001/_bulk

{"index":{"_id":1}}

{"title":"大众汽车首款纯电动ID.4_预售进行时_先订先享"}

{"index":{"_id":2}}

{"title":"保时捷首款纯电动跑车Taycan - 现已到店 - 电驰神往"}

{"index":{"_id":3}}

{"title":"纯电动电动汽车?英国国际贸易部_邀您来投资英国汽车工业"}

{"index":{"_id":4}}

{"title":"四轮电动车_ 电动汽车报价_阿里巴巴采购批发_超多品类低价批发"}

{"index":{"_id":5}}

{"title":"电动汽车之家,为新能源汽车而生 - 第一电动网"}

{"index":{"_id":6}}

{"title":"中国电动汽车网_新能源汽车_电动汽车网"}

{"index":{"_id":7}}

{"title":"电车之家_领先的电动汽车及新能源汽车行业门户网站"}

如果要召回既包含:“电动汽车” 完全匹配,又包含“电动”或“汽车” 分词匹配的全量数据。大致的检索语句如下:


POST index_001/_search

{

 "query": {

   "bool": {

     "should": [

       {

         "match_phrase": {

           "title": {

             "query": "电动汽车",

             "boost": 5

           }

         }

       },

       {

         "bool": {

           "should": [

             {

               "match": {

                 "title": "电动"

               }

             },

             {

               "match_phrase": {

                 "title": "汽车"

               }

             }

           ],

           "minimum_should_match": 2

         }

       }

     ]

   }

 }

}

如上检索部分:完全匹配加了 boost  提升权重。


返回结果如下:

image.png

返回结果按照评分由高到低顺序排列,_id 序列为:5、7、3、6、4 ......


置顶显示_id 为1、2、3的数据,pinned query 实现如下:


GET index_001/_search

{

 "query": {

   "pinned": {

     "ids": [

       "1",

       "2",

       "3"

     ],

     "organic": {

       "bool": {

         "should": [

           {

             "match_phrase": {

               "title": {

                 "query": "电动汽车",

                 "boost": 5

               }

             }

           },

           {

             "bool": {

               "should": [

                 {

                   "match": {

                     "title": "电动"

                   }

                 },

                 {

                   "match_phrase": {

                     "title": "汽车"

                   }

                 }

               ],

               "minimum_should_match": 2

             }

           }

         ]

       }

     }

   }

 }

}

本质是在原来检索语句的基础上,添加了如下部分代码:


"pinned": {

    "ids": [

      "1",

      "2",

      "3"

    ],

    "organic": {

第一:置顶显示的 id ,写法如下:


 "pinned": {

     "ids": [

第二:除了置顶数据之外的其余正常检索语句块内容。只是加了“organic” 包裹一层。其中的检索语句还是原来的写法 ,拷贝过来即可。


返回结果如下:

image.png

返回结果已 pinned(类似做了“广告位”定制),_id 序列为:1、2、3、5 ....... 实现了类百度置顶显示广告的效果。


5、 pinned query 源码解读

5.1 认知前提:源码中最大评分计算方法

float MAX_ORGANIC_SCORE = Float.intBitsToFloat((0xfe << 23)) - 1;

本质下面代码等价:


float max_rst  = (float)Math.pow(2,127);//1.7014118E38

也就是说:MAX_ORGANIC_SCORE 大小为:2 的 127 次幂,是 Elasticsearch float 最大值。


5.2 最大评分作用

正常查询的评分得分不会超过 MAX_ORGANIC_SCORE, 将固定查询(pinned query)的评分设定为:MAX_ORGANIC_SCORE。


5.3  pinned query 保证置顶显示解密

原理:将置顶显示的数据通过 bool 组合查询 + boost 提升权重的方式给设置了 float 最大值评分,这样就能保证置顶显示了。


核心源码实现如下:

image.png

注意细节没有深究,比如:置顶返回的结果显示的是原始评分。


6、小结

读者可能会问:这并没有实现基于特定关键词返回特定数据的需求?其实有了pinned query 再将特定关键词与待置顶显示文章 _id 建立个一对多的映射关系就可以实现。映射关系可以自己内存维护或者借助 redis 实现都可以。


你、我发现的新需求,很可能别人早就发现,且已经提交 Git了。更可怕的是:官方新版本已经实现了!


要注重基础夯实的同时,多关注一下技术动态。两手抓、两手都要硬!

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
7月前
|
机器学习/深度学习 搜索推荐 关系型数据库
号称Elasticsearch 10倍性能搜索引擎到底有多强悍
号称Elasticsearch 10倍性能搜索引擎到底有多强悍
249 0
|
7月前
|
Java 关系型数据库 MySQL
Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
【4月更文挑战第12天】Elasticsearch【问题记录 01】启动服务&停止服务的2类方法【及 java.nio.file.AccessDeniedException: xx/pid 问题解决】(含shell脚本文件)
690 3
|
6月前
|
缓存 开发者 索引
深入解析 `org.elasticsearch.action.search.SearchRequest` 类
深入解析 `org.elasticsearch.action.search.SearchRequest` 类
|
3月前
|
自然语言处理 搜索推荐 数据库
高性能分布式搜索引擎Elasticsearch详解
高性能分布式搜索引擎Elasticsearch详解
89 4
高性能分布式搜索引擎Elasticsearch详解
|
2月前
|
自然语言处理 搜索推荐 关系型数据库
elasticsearch学习六:学习 全文搜索引擎 elasticsearch的语法,使用kibana进行模拟测试(持续更新学习)
这篇文章是关于Elasticsearch全文搜索引擎的学习指南,涵盖了基本概念、命令风格、索引操作、分词器使用,以及数据的增加、修改、删除和查询等操作。
28 0
elasticsearch学习六:学习 全文搜索引擎 elasticsearch的语法,使用kibana进行模拟测试(持续更新学习)
|
2月前
|
开发框架 监控 搜索推荐
GoFly快速开发框架集成ZincSearch全文搜索引擎 - Elasticsearch轻量级替代为ZincSearch全文搜索引擎
本文介绍了在项目开发中使用ZincSearch作为全文搜索引擎的优势,包括其轻量级、易于安装和使用、资源占用低等特点,以及如何在GoFly快速开发框架中集成和使用ZincSearch,提供了详细的开发文档和实例代码,帮助开发者高效地实现搜索功能。
164 0
|
2月前
|
自然语言处理 搜索推荐 Java
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(一)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图
55 0
|
2月前
|
存储 自然语言处理 搜索推荐
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
37 0
|
7月前
|
存储 自然语言处理 搜索推荐
分布式搜索引擎ElasticSearch
Elasticsearch是一款强大的开源搜索引擎,用于快速搜索和数据分析。它在GitHub、电商搜索、百度搜索等场景中广泛应用。Elasticsearch是ELK(Elasticsearch、Logstash、Kibana)技术栈的核心,用于存储、搜索和分析数据。它基于Apache Lucene构建,提供分布式搜索能力。相比其他搜索引擎,如Solr,Elasticsearch更受欢迎。倒排索引是其高效搜索的关键,通过将词条与文档ID关联,实现快速模糊搜索,避免全表扫描。
274 10
|
6月前
|
存储 搜索推荐 关系型数据库
【搜索引擎】elastic search核心概念
【搜索引擎】elastic search核心概念
52 0