基于 Elasticsearch 的站内搜索引擎实战

article/2025/10/7 3:41:01

站内搜索,可以认为是针对一个网站特性内容的搜索功能。由于内容、格式可控,站内搜索比全网搜索的实现要简单很多。

简书这个网站本身自带一个搜索,但是缺乏针对个人文章的搜索,所以本文的实战内容是解决这个痛点。

代码在 https://github.com/letiantian/jianshu-site-search,可以使用下面的方式把代码下载下来查看:

git clone https://github.com/letiantian/jianshu-site-search.git

代码在Python2.7下运行。需要安装以下依赖:

pip install elasticsearch==6.0.0 --user
pip install uniout --user
pip install requests --user
pip install beautifulsoup4 --user
pip install Django --user

1. 数据源

如果是简书给自己做个人搜索,从数据库里拿就行了。

我这种情况,自然用爬虫抓取。

1.1 抓取什么内容?

抓取某个人所有的文章,最终是URL标题正文三个部分。

1.2 如何抓取?

以http://www.jianshu.com/u/7fe2e7bb7d47这个(随便找的)用户主页为例。7fe2e7bb7d47可以认为是这个用户的ID。
文章地址类似http://www.jianshu.com/p/9c2fdb9fa5d19c2fdb9fa5d1是文章 ID。

经过分析,可以以此请求下面的地址,从中解析出文章地址,得到地址集合:

http://www.jianshu.com/u/7fe2e7bb7d47?order_by=shared_at&page=1
http://www.jianshu.com/u/7fe2e7bb7d47?order_by=shared_at&page=2
http://www.jianshu.com/u/7fe2e7bb7d47?order_by=shared_at&page=3
// ... page的值不断增加
// ... 当page不存在的时候,简书会返回page=1的内容,这时候停止抓取

然后,依次抓取文章内容,保存下来。

crawler.py 用于抓取文章,使用方法:

python crawler.py 7fe2e7bb7d47

文章对应的网页会保存到data目录,用文章ID命名。

2. 最简单的搜索引擎实现

对于每个搜索词查看每个文章的标题和正文中有无该词:

  1. 标题中有该搜索词,为该文章加2分。
  2. 正文中有该搜索词,为该文章加1分。

一篇文章命中的搜索词越多,分值越高。

将结果排序输出即可。

代码实现在simple_search.py ,使用方法:

$ python simple_search.py 人民 名义 
你输入了: 人民 名义
搜索结果:url:    http://www.jianshu.com/p/6659d5fc5503
title:  《人民的名义》走红的背后 文化产业投资难以言说的痛
score:  6url:    http://www.jianshu.com/p/ee594ea42815
title:  LP由《人民的名义》反思 GP投资权力真空怎么破
score:  6url:    http://www.jianshu.com/p/4ef650769f73
title:  弘道资本:投资人人贷、ofo 人民币基金逆袭的中国样本
score:  3

这种方法的缺点是:

  • 因为是遍历每个文章,文章变多后,速度会变慢
  • 搜索结果排序不理想
  • 没有引入中文分词特性

3. 基于 Elasticsearch 的实现

Elasticsearch 是一个通用的搜索引擎解决方案,提供了优雅的 HTTP Restful 接口、丰富的官方文档。 阮一峰为它写了一份简明易懂的教程:全文搜索引擎 Elasticsearch 入门教程,推荐阅读。

Elasticsearch 基本原理:

  1. 对搜索内容进行分词,得到若干搜索词。
  2. 通过倒排索引找到含有搜索词的文章集合。
  3. 通过TF-IDF、余弦相似性计算文章集合中每个文章和搜索内容的相似性。
  4. 根据相似性进行排序,得到搜索结果。

3.1 环境搭建

我们先搭建环境:

  1. 安装Java。
  2. 官网下载最新的 6.0.0 版本,解压。
  3. 安装ik分词插件。
    ./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.0.0/elasticsearch-analysis-ik-6.0.0.zip
    
    或者下载下来解压到Elasticsearch的plugins目录。
  4. 启动:
    ./bin/elasticsearch
    

环境搭建完成。

3.2 创建索引

python es_create_index.py

创建时指定了分词器。

3.3 索引数据

python es_index_data.py

为了防止一篇文章被重复索引,添加索引时 Document ID 设置为文章 ID。

3.4 搜索

python es_search.py 人民的名义

高亮搜索结果:

python es_hl_search.py 人民的名义

3.5 基于web的搜索

基于Django实现了一个简单的web界面。运行:

python webui/manage.py runserver

浏览器访问http://127.0.0.1:8000/即可。体验效果:

4. 关于 Elasticsearch 的一些思考

4.1 如何看待停止词?

停止词是非常常见的单词,例如the等。一般用法是在分词后去掉停止词,然后进行索引。这种做法的常见理由是减少索引大小。同时,从理论上看,也可以提升检索速度。
相应的,这里有两个问题需要探讨:

  1. 索引大小的减小量是什么数量级,如果只是减少了1%,这种优化并无必要。
  2. 检索速度的提升是什么数量级,如果只是提升1%,说服力并不大。

是否能达到业务的需求才是目标。如果需要在搜索这个词的时候有结果,那么上面的做法就是不合理的。

我更倾向于底层索引不启用停止词,而是根据业务需求在业务层进行必要的停止词处理。

4.2 防止深度搜索

要Elasticsearch返回搜索结果的第10001条到第10010条数据,是一个耗时的操作,因为Elasticsearch要先得到打分最高的前10010条数据,然后从中取出第10001条到第10010条数据。

用户感知到的搜索界面是分页的,每页是固定数量的数据(如10条),用户会跳转到第1001页的搜索结果吗?不会。第1001页的搜索结果有意义吗?没有意义,用户应该调整搜索词。

综上,应限制用户得到的搜索结果数量。

4.3 处理海量数据

本文的示例的数据由一个用户的所有文章组成,数据量很小。如果简书全站搜索也是用Elasticsearch,它能处理好吗?

事实上,Elasticsearch 支持分片和分布式部署,能近实时的处理海量数据。注意,索引耗时会很大,但是搜索很快。

4.4 如何在搜索结果中加入推广内容

推广内容本身也可以被Elasticsearch索引起来,根据情况插入搜索结果中就行了。

( 完 )

转自《樂天笔记》 原文链接 https://www.letiantian.me/site-search-tutorial/


http://chatgpt.dhexx.cn/article/IfWqB1DF.shtml

相关文章

使用swiftype实现站内搜索

本人博客opiece.me,欢迎访问。 前言 首先,以下的内容是基于最新的swifytpe的教程,应该是2.0.0。 站内搜索顾名思义就是将范围限定在你的网站内,以此范围进行关键字搜索。 常见的站内搜索是google和baidu的,但是现在…

Compass实战 站内搜索

今天早上打算对这两天学习的Lucene以及Compass总结一下,想来想去,还是写个小项目来验证最好了。于是就有了今天的这篇文章。难易程度适合对于Compass或者Lucene刚入门的童鞋,大牛看到后望轻喷 :-) 项目预览项目需求项目目录核心处理 发帖部分查询部分总结项目预览 项目需求 …

html中的搜索

目录 hello😄 form表单🍉 form的语法🍊 from的属性🍊 提交?重置?🍊 表单按钮(html)🔍 JavaScript提交表单🔍 JavaScript重置表单&#x1f…

必应(Bing)的站内搜索 site:<域名> <搜索内容>

最近在备考OCP,发现有一个网站的题库很好,就是www.examtopics.com,有很多Oracle的考题,都是在这里面搜到的,而且每道题都有人讨论。 为了加快搜索速度,提高精度,可以用Bing在这个网站内搜索&am…

百度站内搜索使用教程

最近做了一个博客CMS网站,用到了百度站内搜索,做一些必要的笔记,一来是对自己学习的知识的巩固,二来对有同样问题的人有参考作用 文章目录 一 使自己的网站被百度收录二 获取百度站内搜索代码三 总结 声明一下,我本人很…

利用免费的必应 Bing 自定义搜索打造站内全文搜索

简介 百度的站内搜索不做了,唉,果然免费的不永久。我们看看 Bing 的,每个月有 1000 次免费的调用 bing search api 的次数。不同客户可以多申请几个就行了。 申请入口: https://www.customsearch.ai,官方简介页面官方…

html百度站内搜索代码,网站添加百度站内搜索的教程

zblog博客程序中可以在侧边栏中添加搜索功能,但是让人郁闷的是如果没针对搜索使用搜索插件,那情况简直让人抓狂,还好我们可以使用百度的站内搜索功能,一方面可以节省网站的资源,另一方面可以增加百度的收率几率。 关于…

站内搜索

使用“site:”或者“domain:”来实现站内搜索 如果你想在一个特定的网站上来进行搜索,在众多庞大的信息流中找到你想要的信息, 在上篇中(http://blog.csdn.net/liunian02050328/article/details/8220379)介绍在java编程的环境下实现站内搜索,…

计算机网络中的ping什么意思,PING命令是什么?PING使用方法和参数详解

PING命令是用来检查本机于网络上的电脑是否正常通信的一个命令,作为一个网站的管理员、单位的网管这也是一个必会的命令。 因为网络中所有的电脑都有一个单独不会重复的IP地址,我们使用PING命令给目标IP地址发送一个数据包,对方就要返回一个同…

常见的ping命令

1.ping 延时和丢包 开始--运行---输入cmd---输入ping IP(IP为所要ping的服务器的IP) 常与 -t 选项结合使用 ctrlc结束 延时主要看时间列 看时间得数值和波动 丢包 ---出现请求超时 2.追踪路由 tracert IP 注意: 追路由 --一般追3次 …

ping命令常见参数使用详解

winR 输入cmd 回车 进入命令窗口 输入ping baidu.com 回车可以查看网络连接。 ping [-t]参数是用来不断的ping对方主机,直到手动停止,使用ctrlc。Windows默认是四次停止。 [-l](-L)参数用来设定数据包的大小的,在默认的…

Linux 常用ping命令详解

一、用法 Usage: ping [-aAbBdDfhLnOqrRUvV] [-c count] [-i interval] [-I interface][-m mark] [-M pmtudisc_option] [-l preload] [-p pattern] [-Q tos][-s packetsize] [-S sndbuf] [-t ttl] [-T timestamp_option][-w deadline] [-W timeout] [hop1 ...] destination二…

CentOS7里ping命令详解

ping 功能简述:Linux系统的ping命令是常用的网络命令,它通常用来测试与目标主机的连通性,我们经常会说“ping一下某机器,看是不是开着”、不能打开网页时会说“你先ping网关地址192.168.1.1试试”。它通过发送ICMPECHO_REQUEST数…

ping命令

在网络中ping是一个十分强大的TCP/IP工具。它的作用主要为: (1)用来检测网络的连通情况和分析网络速度;(2)根据域名得到服务器IP;(3)根据ping返回的TTL值来判断对方所使…

Ping命令的用法

ping基本使用详解 在网络中ping是一个十分强大的TCP/IP工具。它的作用主要为: (1)用来检测网络的连通情况和分析网络速度; (2)根据域名得到服务器IP; (3)根据ping返回…

ping命令简单总结

ping测失败是最长出现的网络故障,面对ping不通的问题,需要有一个排查顺序,接下来就简单总结下: 1、ping命令简介 当192.168.1.1向192.168.1.2发出ping测,ping命令生成固定格式的ICMP数据请求包,ICMP协议将…

ping命令基本使用详解

ping命令原理 ping命令是用来探测本机与网络中另一主机之间是否可通的命令,如果两台主机之间ping不通,则表明这两台主机不能建立起连接。 ping命令位于7层协议的网络层。 ping 命令是基于 ICMP 协议来工作的,ICMP为 Internet 控制报文协议。…

Linux ping命令详解

ping命令用来测试主机之间网络的连通性。执行ping指令会使用ICMP传输协议,发出要求回应的信息,若远端主机的网络功能没有问题,就会回应该信息,因而得知该主机运作正常。 语法 ping(选项)(参数) 选项 -d:使用Socket的SO…

ping命令详解 ping不通处理方法

概述: Ping命令是一种用来测试ip层网络层可达的命令,属于icmp层的探查消息。当网络访问出现故障时,用来执行测试网络导通性,根据ping的结果回显来判断问题可能在哪里? ping命令发出包是icmp协议的查询消息&#xff0c…

ping 命令的基本使用

ping 命令的基本使用 一、主要作用二、返回值参数的意义三、ping参数四、常用1、-c2、-n3、-i4、-p5、-r6、-R7、-s8、-S9、-t10、批量ping网段 五、如何禁止他人ping你的IP 一、主要作用 1.用来检测网络的连通情况和分析网络速度 2.根据域名得到服务器ip 3.根据ping返回的TTL…