拓展阅读

搜索引擎-01-概览

搜索引擎-02-分词与全文索引

搜索引擎-03-搜索引擎原理

Crawl htmlunit 模拟浏览器动态 js 爬虫入门使用简介

Crawl jsoup 爬虫使用 jsoup 无法抓取动态 js 生成的内容

Crawl WebMagic 爬虫入门使用简介 webmagic

详细介绍一下搜索引擎

搜索引擎是一种通过互联网收集、组织和提供信息的工具,它能够帮助用户在互联网上查找到与其查询相关的信息。

搜索引擎的工作原理是通过爬虫程序(也称为蜘蛛或机器人)自动收集互联网上的网页,并将这些网页内容存储到搜索引擎的数据库中。

当用户输入查询请求时,搜索引擎会根据其算法从数据库中找到相关的网页,并按照一定的排序规则展示给用户。

以下是搜索引擎的一般工作流程:

  1. 爬取网页内容:搜索引擎的爬虫程序会从互联网上抓取网页的内容。这些爬虫程序会根据一系列算法遍历互联网上的链接,获取网页内容,并将其存储到搜索引擎的数据库中。

  2. 建立索引:一旦网页内容被抓取,搜索引擎会对其进行分析和处理,提取其中的关键信息,并建立索引。索引是搜索引擎用来加快查询速度的数据结构,通过索引,搜索引擎可以快速地找到与用户查询相关的网页。

  3. 处理用户查询:当用户输入查询请求时,搜索引擎会根据用户的查询词在索引中查找相关的网页。搜索引擎会使用一系列算法对网页进行评分,以确定哪些网页与用户查询最相关,并按照一定的排序规则将其展示给用户。

  4. 展示搜索结果:搜索引擎会将查询结果以列表的形式展示给用户。通常,搜索引擎会将最相关的网页排在前面,并提供一些额外的信息,如网页摘要、链接等,以帮助用户快速找到他们需要的信息。

搜索引擎的性能取决于其爬虫程序的效率、索引的质量以及搜索算法的准确性。

一些知名的搜索引擎包括谷歌、百度、必应等,它们通过不断优化其算法和技术来提高搜索结果的质量和准确性,以满足用户不断增长的搜索需求。

搜索引擎的实现原理

搜索引擎的实现原理涉及多个方面,包括网页抓取、索引构建、查询处理和结果排序等。以下是搜索引擎的一般实现原理:

  1. 网页抓取
    • 搜索引擎使用爬虫程序(也称为蜘蛛或机器人)自动从互联网上抓取网页内容。
    • 爬虫程序根据一系列算法遍历互联网上的链接,并递归地抓取网页内容。
    • 抓取的网页内容通常包括 HTML、CSS、JavaScript 等,并可能包括图片、视频等多媒体内容。
  2. 索引构建
    • 抓取的网页内容经过解析和处理,提取其中的关键信息,如标题、正文内容、链接等。
    • 搜索引擎使用这些关键信息构建索引,以加速后续的查询处理。
    • 索引通常使用倒排索引(Inverted Index)数据结构,将关键词映射到包含该关键词的网页列表上。
  3. 查询处理
    • 当用户输入查询请求时,搜索引擎会根据用户输入的关键词在索引中查找相关的网页。
    • 搜索引擎可能会对查询进行预处理,如分词、去除停用词等。
    • 根据查询的关键词,在索引中查找包含这些关键词的网页,并计算它们与查询的相关性。
  4. 结果排序
    • 搜索引擎会根据一系列算法对查询结果进行排序,以确定最相关的网页并将其展示给用户。
    • 常用的排序算法包括 TF-IDF(词频-逆文档频率)、PageRank 等,这些算法考虑了网页的内容质量、链接关系、用户行为等因素。
    • 结果排序也可能会考虑用户的搜索历史、地理位置等个性化信息,以提供更符合用户需求的搜索结果。

搜索引擎的实现原理涉及大量的算法和技术,包括文本处理、数据结构、机器学习等领域的知识。

搜索引擎的性能取决于其算法的准确性和效率,以及其系统的可扩展性和稳定性。

因此,搜索引擎的设计和实现是一个综合性的工程,需要考虑多方面的因素。

java 网页爬虫有哪些优秀的开源工具?

在Java领域,有许多优秀的开源工具可以用于网页爬虫的开发。

以下是一些常用的Java网页爬虫框架和工具:

  1. Jsoup
    • Jsoup 是一款专门用于解析、处理 HTML 和 XML 文档的 Java 库。
    • 它提供了简单、直观的 API,方便开发者对网页进行解析、提取信息等操作。
    • Jsoup 适用于简单的网页抓取和信息提取任务。
  2. WebMagic
    • WebMagic 是一个基于 Java 的高级网络爬虫框架,具有高度的灵活性和扩展性。
    • 它提供了一套完善的 API 和组件,支持异步、分布式爬取等功能。
    • WebMagic 支持多种网页抓取方式,包括普通 HTTP、Ajax、Selenium 等。
  3. Crawler4j
    • Crawler4j 是一个轻量级的 Java 网络爬虫框架,基于 Apache Nutch 实现。
    • 它提供了简单易用的 API,支持多线程、分布式爬取等功能。
    • Crawler4j 可以用于快速搭建简单的网络爬虫应用。
  4. Apache Nutch
    • Apache Nutch 是一个强大的开源网络爬虫和搜索引擎系统,采用 Java 编写。
    • 它支持分布式爬取、网页抓取、内容索引等功能,可用于构建大规模的搜索引擎系统。
    • Apache Nutch 基于 Hadoop 和 Solr 构建,具有良好的可扩展性和性能。
  5. Heritrix
    • Heritrix 是一个专门用于构建网页存档(Web Archive)的开源网络爬虫。
    • 它是 Internet Archive(互联网档案馆)的核心组件之一,用于抓取和存档互联网上的网页。
    • Heritrix 使用 Java 编写,支持高度定制化和配置。

这些开源工具各有特点,可以根据具体需求选择合适的工具。

例如,对于简单的网页抓取任务,可以选择 Jsoup;对于复杂的爬虫应用,可以考虑使用 WebMagic 或 Apache Nutch 等框架。

java 有哪些优秀的索引+查询开源工具?

在Java领域,有几种优秀的索引和查询开源工具可供选择,以下是其中一些:

  1. Apache Lucene
    • Apache Lucene 是一个全文搜索引擎库,用于添加搜索功能到应用程序中。
    • 它提供了一个简单易用的 API,用于创建和管理索引,并执行高效的全文搜索。
    • Lucene 支持诸如分词、索引、查询等功能,并具有高度可定制性。
  2. Elasticsearch
    • Elasticsearch 是一个分布式的实时搜索和分析引擎,构建在 Apache Lucene 基础之上。
    • 它提供了 RESTful API,用于存储、检索和分析数据,并支持分布式搜索和实时数据分析。
    • Elasticsearch 具有强大的全文搜索和聚合功能,适用于构建大规模的搜索引擎和日志分析系统。
  3. Apache Solr
    • Apache Solr 是一个基于 Lucene 的开源搜索平台,用于构建搜索应用和网站。
    • 它提供了一个功能丰富的 RESTful API,用于索引、查询和分析文档。
    • Solr 具有强大的全文搜索和文档聚合功能,支持高度定制化和扩展性。
  4. Hibernate Search
    • Hibernate Search 是一个基于 Hibernate ORM 的全文搜索引擎。
    • 它提供了简单易用的 API,用于将 Java 对象映射到全文索引,并执行全文搜索和查询。
    • Hibernate Search 可以与各种关系型数据库集成,适用于构建基于对象的全文搜索应用。

这些工具各有特点,可以根据项目需求和复杂度选择合适的工具。

例如,对于简单的全文搜索功能,可以选择 Lucene 或 Hibernate Search;对于大规模的分布式搜索和实时分析,可以考虑使用 Elasticsearch 或 Solr。

java 有哪些优秀的结果排序开源工具?

在Java领域,有一些优秀的结果排序开源工具可以帮助你实现高效的搜索结果排序。

以下是其中一些:

  1. Apache Solr
    • Apache Solr 是一个基于 Apache Lucene 的开源搜索平台,它提供了强大的搜索和排序功能。
    • Solr 支持多种排序算法,包括基于相关性的排序、按字段排序、自定义函数排序等。
    • 它还提供了丰富的可配置性和扩展性,可以根据需求定制排序逻辑。
  2. Elasticsearch
    • Elasticsearch 是一个分布式实时搜索和分析引擎,也是基于 Lucene 的。
    • 它提供了多种排序功能,包括按相关性、按字段值、按评分等排序。
    • Elasticsearch 还支持复杂的排序需求,如自定义脚本排序、地理位置排序等。
  3. RankLib
    • RankLib 是一个用于排序学习和排名的 Java 库,由 Lemur Project 开发。
    • 它实现了许多排序算法,包括 LambdaMART、RankNet、Coordinate Ascent等。
    • RankLib 提供了丰富的功能和 API,适用于在搜索引擎和推荐系统中应用排序学习算法。
  4. Learning to Rank(LTR)
    • Learning to Rank 是一个 Java 实现的学习排序框架,用于构建和部署排序模型。
    • 它提供了多种机器学习算法,如 RankNet、LambdaMART、ListNet 等。
    • Learning to Rank 框架可以与 Lucene、Solr 等搜索引擎集成,用于优化搜索结果排序。

搜索引擎

对于搜索引擎, 在索引量和搜索量大到一定程度的时候, 索引更新的效率会逐渐降低, 服务器的压力逐渐升高, 因此基本上整个搜索引擎的利用率可以说是越来越低了, 并且随着海量数据存储带来的困难, 设计一个良好的分布式搜索引擎将是一个搜索引擎能否面相未来发展的关键因素了。

核心问题

那么分布式搜索引擎的最主要的核心问题是哪些呢?

  • 分布的信息获取和计算以及对此进行的数据统一

这里面包括爬虫/或者相应的数据获取机制的分布, 对信息进行加工的统一管理

  • 数据处理后的分布存储和管理

主要是文件的准确定位和更新,增加,删除,移动的机制

  • 前端搜索服务的分布

主要处理大规模并发请求时的分发机制

分布式搜索引擎的分类

基于以上3个基本需求, 基本上可以构造如下4类的分布式搜索引擎:

  1. 分布式元搜索引擎

  2. 散列分布搜索引擎

  3. P2P 分布搜索引擎

  4. 局部遍历型搜索引擎

下面逐步介绍以上4类可扩展的搜索引擎:

1. 分布式元搜索:

拥有多个单个的搜索引擎, 中心搜索引擎是利用这些分布的单个的搜索引擎的结果进行撮合得到完整的结果。

这样的设计方案要求各个单元的搜索引擎拥有相同的排序算法和基本相同的数据输出结构,以便由中心搜索进行整理。

对于这类的搜索引擎,关键的设计是要求每一个单元所拥有的索引不构成重复,但是进行数据的采集(爬虫)时可以采取独立的系统获取后再按照规则分布到各个单元上。 优点,设计简单,快速,并且任何一个单元可以随时的摘掉但并不影响太大。 缺点,对于大规模的并发并非好的解决办法

2.散列分布搜索引擎

根据Query对索引服务器和文档服务器进行散列,做到对于任何的索引词能够准确的定位到具体的索引服务器并从而定位到正确的文档服务器。

优点,抗压,设计简单

缺点,对于单个索引服务器或者文档服务器的容量等动态的调整较困难

3.Peer 2 peer 搜索引擎

著名的Napster就是这样的一种设计,利用集中方式的索引,配合分布于世界各地的单个的计算机形成的文件源,构成了世界上最庞大的p2p搜索引擎之一。

这 种设计里的中心索引服务器只记录一些相对关键的信息,例如位置(IP,序列号),歌曲的名字,作者等,其它的信息一概可以从任何在线并且拥有本条全面信息 的计算机上获取。同时p2p也可以根据搜索建立一些中间路由的缓存,即将一些搜索结果存在单个或者相近的节点上,加快搜索速度。

优点,可以超级大,基本上不需要有维护成本

缺点,中心服务器的更新效率很低,信息源不稳定

4. 局部遍历型搜索引擎

这类的搜索引擎又可以采用多种设计方案,其中比较可行的是对信息进行聚类后建立信息树,搜索时只需要从树的一个分支下去遍历便可以了。

局部遍历应当有一定的规则,并且在设计初期就需要对每一个加入的索引进行相对准确的位置安排,使得放置在合适的节点上,以保证搜索的效率。

优点,容易解决抗压,搜索精度高,搜索效率高

缺点,设计复杂,调整索引所在节点的位置不易

总体来说,搜索引擎的设计方法可以很多,这里只是抛砖引玉,相信未来会有更多的巧妙的设计方案出现。

电商搜索引擎

首先,我想说的是电商搜索引擎和普通的搜索引擎有很大的差别,因为电商搜索引擎主要是解决用户要“买什么”,而通用搜索引擎主要是解决用户“搜什么”。

比如同样搜索一个词“百年孤独”,电商的搜索肯定是给你推荐这本书的商家,而百度主要是告诉你:《百年孤独》是一本书。

电商搜索引擎的特点

众所周知,标准的搜索引擎主要分成三个大的部分,第一步是爬虫系统,第二步是数据分析,第三步才是检索结果。

首先,电商的搜索引擎并没有爬虫系统,因为所有的数据都是结构化的,一般都是微软的数据库或者Oracle的数据库,所以不用像百度一样用“爬虫”去不断去别的网站找内容,当然,电商其实也有自己的“爬虫”系统,一般都是抓取友商的价格,再对自己进行调整。

第二点,就是电商搜索引擎的过滤功能其实比搜索功能要常用。甚至大于搜索本身。什么是过滤功能?一般我们网站买东西的时候,搜了一个关健词,比如尿不湿,然后所有相关品牌或者其他分类的选择就会呈现在我们面前。对百度而言,搜什么词就是什么词,如果是新闻的话,可能在时间上会有一个过滤的选项。

第三点,电商搜索引擎支持各种维度的排序,包括支持好评、销量、评论、价格等属性的排序。而且对数据的实时性的要求非常高。对一般的搜索引擎,只有非常重要的网站,比如一些重量级的门户网站,百度的收录是非常快的,但是对那些流量很小的网站,可能一个月才会爬一次。电商搜索对数据的实时性要求主要体现在价格和库存两个方面。

电商搜索引擎另一个特点就是不能丢品,比如我们在淘宝、天猫开了个店铺,然后好不容易搞了一次活动,但是却搜不到了,这是无法忍受的。除此之外,电商搜索引擎与推荐系统和广告系统是相互融合的,因为搜素引擎对流量的贡献是最大的,所以大家都希望把广告系统能跟其融合。当然,还有一点非常重要,就是要保证绝对的高可用,而且不能宕机。

电商搜索引擎的架构

因为电商搜索引跟一般的搜索引擎区别很大,所以在架构的设计上也独具特色。

首先,搜索引擎的实现方式有很多种,有谷歌、百度、搜狗这种非常大的公司,也有京东、淘宝、当当这样的电商搜索引擎,很多中小型的电商可能更喜欢用一个开源的搜索引擎。

所以总的来说,主要包括以下这几种方式:

第一种是“Lucene+自己封装”,只用来做检索,然后封装,后面所有的ES,这两个是完整的解决方案,而且包括索引所有的东西,只需要部署好业务逻辑,然后查找结果就可以了。

第二种就是Solr,这是一个高性能,采用Java5开发,基于Lucene的全文搜索服务器。同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面,是一款非常优秀的全文搜索引擎。

第三种是ElasticSearch,这是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,目前使用的也非常多。

这里提一下,当当的搜索引擎是自己实现的。现在,新兴的互联网公司大部分都是使用第一种或者第二种,数据量比较大的一般采用第三种。

电商搜索引擎标配模块

接下来我想讲一下,如果我们自己做一个搜索引擎的话需要实现哪些功能(上图是电商搜索引擎的标准模块),其实不止是电商搜索引擎,除了通搜的搜索引擎,其他的搜索引擎也是使用这样的标配。

对检索模块而言,首先是对用户的意图进行分析,根据用户的搜索词来进行纯算法的实现。

比如用户的搜索词是“黑包包”,其实用户的本意就是买一个黑色的包,但是这个“包”可以跟别的词组合在一起,甚至在搜索结果中会出现“包子”。

所以,这就需要query分析系统来做,告诉检索系统,你需要主要在服装鞋帽中的分类去找,而不是生鲜食品类。

设计到技术层面,当当网使用的是C++。如果构建一个性能好的系统,一些老一点的公司,大家都是在使用C++或者是C语言。不止是当当网,其实很多公司都是使用的C或者C++实现的搜索引擎。

数据更新模块

第二个模块就是数据更新模块,该模块负责生成索引。而数据中心模块主要做的事情,就是将原始的结构化数据,变成一个可供检索系统使用的搜索数据库。当然,数据更新模块和检索模块是分开还是合并呢?其实从本质上讲,都是一堆代码,完全可以写在一个进程里。当然,也可以分开,通过网络往外输入,各自都有道理。

第一种是简单粗暴型的,如果是普通电商,像生鲜电商,数据量不大,实时性、季节性很强,就可以把两个系统用一个进程来完成。

但是如果到了百万、千万甚至上亿级别的话,就不可能部在一台机器上了。

上图就是当两个系统合并在一起的时候,红色部分就是检索系统,黄色部分是上游产生数据的系统,如果是淘宝的话,对接就是淘宝的商户,当当网对接是市场部的人员,他们将数据录入系统,推到数据库,然后向下进行传送,最终建立一个索引。

上图中的蓝色部分就是业务逻辑,因为电商的搜索引擎业务需求量非常高,尤其是现在大家都喜欢用手机进行购物,像手机专享价就是一个新的业务,这也意味着需要一个专用的模块来处理这些商用的逻辑。

此外,就是用户行为的分析,我们搜集到的日志还有其他相关的数据都会存到Hadoop集群上去,通过离线计算,然后传给商业模块或者排序模块进行排序和打分,并提供给用户更好的使用体验。

出问题是不可避免的!如何解决?

虽然整理来看,设计的思路是非常合理的,但是还是会出现问题。

一般而言,一个成熟的电商搜索系统,它的问题都很集中,要这几种情况:首先就是Bug,当然这是所有系统都会遇到的问题;第二个就是并发,但是搜索系统是没办法进行分库分表,所以能做的就是索引切分;最后一点就是监控,包括问题追踪、日志系统和监控系统,那么为了解决这些问题,我们应该怎么做?

首先,针对Bug问题,只能靠自动化运维去解决(这里也推荐使用OneAPM工具);第二个就是高并发的问题,目前主要是靠缓存和横向扩展。而缓存和横向扩展怎么应用到系统中去,这个很关键。很多人也说可以换一种语言,比如讲Python换成C++,但实际情况下,换语言并不能解决并发的问题,好的数据结构的设计比换一种语言更能提高性能,所以一般解决高并发问题的也就是缓存和横向扩展。

第三个就是使用用FLUME日志系统(Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受方(可定制)的能力)。其实,Flume会把集群上每一个节点的日志全都收集起来,这样做起来有两个好处,第一是现场出问题,可以先回滚出Bug,然后进行查询。第二个就是对日志进行搜集,然后做用户行为分析,查看用户点击了多少次,从何处导入的流量等等,从而便于更好的进行排序。

然后讲一下缓存的问题。一般搜索的缓存可能分为两级缓存,据我观察,像搜狗可能是使用页面级缓存,而百度可能用的是索引级的缓存。比如在搜狗搜索一个词,开始时可能需要40毫秒,然后再搜的话,就可能一下子降到1毫秒。这就是页面级缓存。而百度可能第一次搜索用了40毫秒,第二次就是25毫秒,它并不是把页面给缓存下来,而是将索引的倒排链缓存,级别其实是不一样的。

电商搜索很多使用的是两级缓存,对于特别热门的词汇,我们可以做页面级缓存,而页面级缓存的时间只有15秒到20秒。但是像价格这样的东西不能缓存,需要前台页面去反拉价格。第二级就是索引级别的缓存,实际上也是自建的一个缓存系统。另外,排序也有缓存,因为排序的结果不太会有太大的变化。

上图是当当的搜索架构,这里有一个集群是做数据分析的,上面备满了数据。

首先,集群之间采用什么样的通讯方式?

我们主要使用ZMQ(这是一个简单好用的传输层,像框架一样的一个 socket library,使得 Socket 编程更加简单、简洁和性能更高。是一个消息处理队列库,可在多个线程、内核和主机盒之间弹性伸缩)。原因其实只有一个,就是快,非常快,比较适合数据量比较大的业务。

如何避免冷启动?

最后就是冷启动的问题,这个问题是很多电商网站都很头疼的问题。尤其是随着电商网站的商品数量达到一定量级的时候,比如已经上亿了,像淘宝、天猫的话应该更多。如果重建了一次索引需要启动,或者新上线了一个业务模块,需要重启系统,是很麻烦的。

当然,当集群大了以后有很多方法,比如分开启动之类的,至于技术嘛,一般索引的加载都是使用Lunix标准的MMAP(MMAP将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。MMAP在用户空间映射调用系统中作用很大),这样启动速度会很快,但是系统会有预热时间,前面一些时间的查询会比较慢

如果数据量不是特别大的话,而且现在内存也那么便宜,完全可以将数据一次性读入内存,因为mmap的操作毕竟性能没有直接内存来得快。

第三种的话,就是尽量减少做全量数据的频率,避免整个系统的重启,这需要定期做一下索引的优化,把没用的索引干掉。

如果是新上了一个业务模块需要重启集群,这样的事情最好不要发生,这就是架构有问题了,将业务模块变成外部的模块或者插件进行上线才是正确的,不然每上线一个模块需要重启集群,这谁都受不了

ES 结合搜索引擎的例子

首先得先了解一下ES特性,ES检索速度特别快,而且查询的API丰富,还有聚合等等的功能,天生分布式框架。

所以从框架的性能来说,选择ES作为我们项目的搜索模块是毫无问题的。

现在重点就是设计ES中索引字段、索引字段的属性、数据同步方案、确定需要设置权重的字段等。

下面我们来一个个说明理清一下思路。

索引字段

首先是确定索引字段,为什么样将这个放在第一个呢。

因为ES的索引是一旦确定下来就不能做任何的修改了,只能删除重新创建索引。

所以选择好索引字段是非常重要的。我们创建索引的时候要注意以下几点:

  1. 经常变动的数据且要一变动就马上显示的数据,这种数据不要放在ES中。

  2. 不要将不需要的数据库表字段添加到ES索引中,浪费资源。

  3. 不要将经常变动的状态字段放在ES中。

  4. 为了同步数据方便,不要轻易将多张表的字段放在同一个索引中去。

  5. 第五点可能会和第四点相互矛盾,就是尽可能只通过查询ES就可以将数据查询出来,而不是需要二次查询数据库,因为这样很容易照成n+1次查询的出现。

索引字段属性

ES的所有字段也是有一套自己的属性的,基本和Java的类型差不多。既然有类型肯定就会有各种类型之间的差别,比容商品价格的时候,我们就可以将价格这个字段设置为Numeric类型。所以基于项目需求,我们需要注意以下几点内容:

  1. 趣物的名称、分类不需要进行分词,因为我们需要的是精确查询。

  2. 趣物的内容要设置分词,因为我们需要大范围的关键字检索。

  3. 趣物的点赞、收藏、分享数目就可以设置为Numeric类型,方便统计。

数据同步方案

数据的同步方案有两种:

  1. 工具同步:如果索引和数据库表一一对应,索引的字段没有超出数据库表的范围,就可以采用第三方框架来同步数据。这种方式的好处是对代码没有侵入性,直接同步数据库数据到索引中就可以了,缺点是不够灵活,功能被框架限制死。

  2. 代码同步:如果索引和数据库表不是一一对应,甚至还需要进行一些处理。这种情况下我们可以采用跑定时任务的模式,进行程序同步。好处是可控性大大增加了,缺点是对代码的侵入性太大,定时任务出问题不好处理。

数据同步千万不要时时刻刻同步,这样的设计会搞死ES服务,所以一般都是在凌晨或者特定的时间同步一次。

确定权重字段:

什么是权重呢,这就要和排序相挂钩了,相当于SQL中order by类似。

大家想一下淘宝的排序规则就知道了,可以根据发布时间,浏览人数等等进行排序,我们这个项目也一样。所以要预留设置权重的字段,然后可以在后台进行权重配置。这样可以大大的提高程序的扩展性,比如我们可以将发布时间、修改时间、点赞数目、收藏数目、分享数目进行权重设置,这样可以很自由的进行排序规则设置。甚至比如我们平台自己的商品想要放在首页就可以通过权重设置,设置在到第一个中。

经验总结:

设计的时候还要注意,因为趣物模块我们这边分为三种类型,所以ES索引中一定要设置状态这个字段,而且不能进行分词,必须精确查询才可以。

后台需要一个ES管理模块,进行索引的增删改成维护。

因为作为平台都应该是可控的,这样可以大大的降低风险,所以我们一定要预留一些能够处理突发情况的接口。

技术一定要和业务相结合,绝对不能因为技术而用技术,业务需要什么技术我们就用什么技术。

产品设计

这一篇是用产品的角度来思考问题。

由于搜索引擎技术的不断成熟,加上用户的时间越来越珍贵,像搜索这样提高用户检索效率的功能在产品中已经逐渐成为标配。今天我们来谈一下搜索功能的设计。

搜索功能的原理

首先搜索功能的原理主要就是三步:

Step1:对用户输入信息的解读转译

Step2:根据用户的输入信息对内容进行筛选

Step3:将筛选后的结果进行排序

第一步主要是对用户输入的信息进行转译的过程,通过切分用户的输入文本,过滤非相关内容,进行一个关键信息的解读。

第二步主要是对这些转译后的关键文本的结果进行准确率和召回率评估后的筛选。

第三步是根据算法对内容的相关度计算和业务相关性对筛选后的结果进行打分后进行排序。

通过这三步就完成了一个搜索的过程。

看完了搜索的基本原理,我们来看看搜索产品设计中的一些功能和特点。

搜索前的设计

首先看一下搜索前这个场景,在使用搜索前,用户是一种带有相对较明确的目的才会去使用搜索功能。

所以对于搜索前这一场景,我们需要考虑的第一个问题是搜索框在哪里,怎样的交互形式呈现给用户。

一般来说,搜索框有三种常见样式:

  1. 以ICON的形式展示,功能使用在二级页面

  2. 与分类,发现合并出现在一个主tab上

  3. 在首页的顶部bar上直接外露展示

对于天猫这类的电商类产品,由于搜索是个高频刚需,所以一般都会默认置于最显眼的首页,并且大多会配以运营干预的空间,设置一些默认的推广词,给一些特定的商品进行导流曝光。

像开眼视频这类也是一种常见的情况,往往是由于首页的顶部区域有更为重要的结构在展示着,如果像天猫那样进行平铺会破坏一些整体的布局结构,两者相害取其轻,就采取了ICON的形式。

对于像布卡漫画这样的内容产品,搜索和分类在一起的主tab上在结构上其实也是很合理的,分类和搜索都是用以检索的功能,所以将他们进行聚类。

那么一般来说搜索不放在首页展示的原因有:

  1. 通过数据监控发现搜索的使用率不是很高

  2. 由于内容数量的问题,搜索后有比较高概率出现无结果

而第二点原因其实对于很多刚刚起步的APP来说很重要,刚起步的APP一般数据量较小,所以很多往往都是先只提供分类检索,而不提供搜索功能,避免出现提供了功能但却喂不饱用户需求进而导致用户流失的局面。

搜索中的设计

说完了搜索前这个场景,那么我们来聊一聊搜索中的场景对应功能该如何设计。

搜索中场景下有几个比较重要的功能设计点。

1.热门搜索及历史记录:

热门搜索在搜索产品中也算一个比较常见的功能了。

热门搜索需要注意的有以下一些问题:

a. 无搜索结果词不进入热门搜索

b. 后台建立热门搜索的黑名单,将一些违禁词或恶意刷量词进行管控

c. 建立白名单,方便运营对热搜进行排序调整或是手动添加某热搜词

d. 多种内容提供时,热门搜索展示的内容类型分布。

关于d这一条,再解释一下,例如热门搜索有作者,作品,商品。

你是不管哪一种都进行展示,还是根据业务对这几种不同的类型进行占比排布,展示60%作者,30%作品,10%商品,还是只展示搜索作品。这些都是需要由不同的产品形态和业务需要进行调整的。

历史搜索记录这个功能是方便用户进行二次搜索的一个快捷入口,一般都是按照时间顺序排列,最近搜索的在上方,腾讯动漫的这个清空历史记录功能的位置处理的很好,很多APP会放在下方,容易出现搜索记录很多的时候导致这个清空历史记录的功能首屏不可见了。

2.搜索建议

搜索建议这一功能是为了满足用户只记得部分关键字等一些模糊搜索需求时的场景,同时还能节省用户的操作成本,不用全部打完,只打出部分文字就可以给出建议搜索词。

搜索建议的注意点有:

a.搜索建议词的匹配规则

b.搜索建议相关词的高亮

c.完全命中的建议结果有特殊的展示方式

d.一些可操作内容可以考虑是否要前置到建议列表,如播放,收藏

e.同义词的建议

f.智能纠错

g.拼音模糊匹配

关于搜索建议词的匹配规则,在这里稍微展开讲一下。

一般来说的匹配原则为计算文本相关度算法,但对于大多数APP内搜索其实是不用做到这么深入这种程度的。

一般都是将用户输入的文本去依次匹配。

例如用户输入“妖”这个字,会先去检索内容(这里的内容又要考虑到底是匹配作品名/商品名/作者/店铺名/描述等)中第一个字为“妖”开始的,再去检索第二个字为“妖”开始的。得到这些结果后又需要对这些结果进行排序。

一般是按照查询量高低进行排序,如果数据库没有记录这些的话,还可以考虑从该建议词的销量,点击,人气,阅读,评分等维度去进行排序,总之就是把大多数人更加感兴趣的结果排序提前。

关于同义词的建议,这是一个相对高端一点的功能,但是确实能提高检索信息的效率。

解释一下,就是建立一个同义词的关联规则,当用户输入如“鸣人”能够建议出“漩涡鸣人”这样的同义词。

这个相对来说高端一些,要建立关联规则。所以一般非大厂的搜索不用做到这一程度。

先看看淘宝的搜索建议列表,亮点在于提供了细化搜索条件的信息前置,省去了用户到搜索结果页再去进一步选择。

腾讯动漫的搜索建议就是比较传统的像我们上文提到的,从首字开始匹配。而豆瓣的搜索直接省去了搜索建议这一步,豆瓣做的是响应式搜索,用户每次输入停留后会自动进行搜索结果呈现。

将不同分类的查找结果进行了汇聚,可分别点击查看各类型的详细搜索结果列表信息。

像豆瓣和淘宝都提供了搜索时先进行搜索范围的选择,再进行搜索的功能,是为了提高精准度。

搜索后的设计

最后来讲一下搜索行为后这一场景下的一些设计。搜索后其实也就是搜索结果页的设计了。

搜索结果页比较重要的点有:

  1. 自主排序

  2. 筛选条件/筛选器

  3. 无结果的展示,例如猜你想搜等高关联度结果推荐

  4. 搜索结果的默认排序算法

像腾讯动漫的搜索结果,由于不像电商类有搜索结果量大,筛选条件繁多的问题,所以处理比较简洁清晰,采用列表页平铺的样式,同时提供了快速开始阅读的入口。

而腾讯动漫也只有一个系统的默认序,没有提供自主的排序选择。而腾讯的默认排序也比较清晰,先按照文本的相关度检索规则,之后再按照人气值降序排列。

像天猫由于结果量繁多,首先结果的呈现样式采用了橱窗式,提高商品的展示效率。

天猫不仅提供了丰富的自主排序条件,还提供了一个功能强大的筛选器,可支持按品牌,类别,店铺类型,服务折扣,商品所在地这些条件对结果进行进一步的筛选。

小红书的结果亮点是它的标签系统,提供了一些跟你结果相关的标签,成为了仅仅筛选商品/笔记的一个补充,方便用户去发现更多的可能。

开源框架

lucence-核心工具

Solr-开箱即用

ES-成熟工具

个人总结

  1. 目前 ES 是非常受欢迎的,但是作为程序员。应该搞清楚背后的原理,学好 lucence 为以后自己设计做搜索引擎打下基础。

  2. 产品不单单技术的实现,知道产品如何设计也非常重要。

实战的想法

想设计一个自己的搜索引擎。

  1. 爬虫抓取数据:房屋 工作 动漫 书籍 科技 媒体 达人 电影 音乐 娱乐 休闲 生活 旅行 学习 工具 历史 读书 金融 理财 美食 菜谱

  2. 分析整理。

  3. 结合 ES 展现。

参考资料

电商搜索引擎的架构设计和性能优化

elasticsearch搜索引擎设计方案

可扩展搜索引擎的四种设计方案(转)

5分钟带你了解搜索功能如何设计