倒排索引
反向索引(inverted index)更熟悉的名字是倒排索引。
什么是倒排索引: 倒排索引也叫反向索引,通俗来讲正向索引是通过key找value,反向索引则是通过value找key。
举个具体的例子:我们一般是通过标题来找文章内容,即通过目录(正向索引);而反向索引的运用场景就是通过内容来找到是哪一篇文章(标题,作者……),而怎么建立反向索引呢?怎么更快更好地找到结果呢?这个就是搜索引擎做的事了、
正向索引:例如一个“文档1”经过分词,提取了20个关键词,每个关键词都会记录它在文档中的出现次数和出现位置。那我们就可以直接通过对"文档1"Document这个结构进行解析,从而得到每个关键词的信息。
反向索引:那么我们希望通过关键词来找到它在哪几篇“文档”中出现怎么办呢?那么其实在遍历文章的时候,如果当前文章出现了keyword,则对Keyword的结构(简单点可以想成是一个hashmap)添加上这篇文章的信息
再举个生活例子: 当用户在主页上搜索关键词“华为手机”时,假设只存在正向索引(forward index),那么就需要实时扫描完索引库中的所有文档,找出所有包含关键词“华为手机”的文档,再根据打分模型进行打分,排出名次后呈现给用户。因为互联网上收录在搜索引擎中的文档的数目是个天文数字,这样的索引结构根本无法满足实时返回排名结果的要求。
所以,搜索引擎会将正向索引重新构建为倒排索引,即把文件ID对应到关键词的映射转换为关键词到文件ID的映射,每个关键词都对应着一系列的文件,这些文件中都出现这个关键词。从而大大减少了遍历的大小,加快了检索的速度。
本质上是通过设计数据结构,并花了额外的空间去换检索时的时间。
论文查重就是这种的典型应用:B站视频——论文查重是如何实现的——将段落通过标点符号分隔成一个个句子,再将句子每每7个分隔成一个个section,比如长度为9的句子则可以分成3个section,预处理创建preDict={"section1": [doc1, ], "section2": [doc1, ], "section"3: [doc1, ]}
的倒排索引,当进行查重时,也是分隔成句子后每每7个字进行检查是否在preDict中,如果在则是知道了在哪些文章中出现(最简单版)。视频后又提出了增加LCS最长公共子串的增强,有效地检验出了添加“的”字or调整字位置的偷鸡方法——建立4字倒排,如果4个字已经出现在了别的文章A里,则把当前句子S1与文章A中的句子S2进行LCS,如果公共子串长度大于7则判定为重复。
搜索引擎——Elasticsearch
Elastic Stack 如果你没有听过,那么 ELK 一定听过。ELK 是三款软件的简称,分别是 Elasticsearch
、Logstash
、Kibana
组成。那什么是 Elasticsearch呢?——全文搜索是很多网站常见功能,比如 GitHub 站内搜索、JD 商品搜索、B 站视频搜索。Elasticsearch
是当今最火的搜索引擎之一,它的底层基于另外一个 java
开源搜索引擎 Lucene
,是一款开源分布式搜索引擎,并且提供了一系列 REST API
操作接口。
ES的核心概念
- 索引(Index):ES将数据存储于一个或多个索引中。类比传统的关系型数据库领域来说,索引相当于SQL中的一个数据库,或者一个数据存储方案(schema)。索引由其名称(必须为全小写字符)进行标识。一个ES集群中可以按需创建任意数目的索引。
- 类型(type):类型是索引内部的逻辑分区(category/partition),一个索引内部可定义一个或多个类型(type)。类比传统的关系型数据库领域来说,类型相当于“表”。
- 文档(Document):文档是索引和搜索的原子单位,它是包含了一个或多个域(Fild)的容器,每个域拥有一个名字及一个或多个值,有多个值的域通常称为“多值域”,文档基于JSON格式进行表示。每个文档可以存储不同的域集,但同一类型下的文档至应该有某种程度上的相似之处。
- 集群(Cluster):一个或者多个拥有相同cluster…name配置的节点组成,它们共同承担数据和负载的压力。
- 节点(Node):一个运行中的Elasticsearch实例称为一个节点。
ES集群中的节点有三种不同的类型:- 主节点:负责管理集群范围内的所有变更,例如增加、删除索引,或者增加、删除节点等。主节点并不需要涉及到文档级别的变更和搜索等操作。可以通过属性node.masteri进行设置。
- 数据节点:存储数据和其对应的倒排索引。默认每一个节点都是数据节点(包括主节点),可以通过ode.data属性进行设置。
- 协调节点:如果node.master和node.data属性均为false,则此节点称为协调节点,用来响应客户请求,均衡每个节点的负载。
Python操作Elasticsearch
安装es库pip install Elasticsearch
参考:
- python操作ElasticSearch-创建、插入、检索
- 【狂神说Java】ElasticSearch搜索实战仿京东搜索——Java操作ES+仿京东搜索+vue与thymeleft单页面实现前端
附录
docker 运行 Elasticsearch
根据官网推荐,ES配套 Kibana 只能安装 6.8.19, 所以安装
-
拉取镜像:
docker pull docker.io/elasticsearch:7.17.2
,拉取其他版本可见查看镜像版本:docker-search-tag -
es配置文件
1
2
3mkdir -p /home/apollo3d/cl/dockerdata/elasticsearch/config
mkdir -p /home/apollo3d/cl/dockerdata/elasticsearch/data
echo "http.host: 0.0.0.0" >> /home/apollo3d/cl/dockerdata/elasticsearch/config/elasticsearch.yml -
启动容器:
docker run --name es -p 9200:9200 -p 9300:9300 \ -e "discovery.type=single-node" \ -e ES_JAVA_OPTS="-Xms64m -Xmx512m" \ -v /home/apollo3d/dockerdata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \ -v /home/apollo3d/dockerdata/elasticsearch/data:/usr/share/elasticsearch/data \ -v /home/apollo3d/dockerdata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \ -d docker.io/elasticsearch:7.17.2
,注:<image_id>
可以通过docker images
查看刚刚pull下来的镜像;需要去ESC上打开防火墙的指定端口; -
测试:浏览器访问 Elasticsearch 地址:
ECS_IP:9200
, 如果返回JSON数据则启动正确 -
安装 ik 分词器
1
2
3
4
5
6# 进入es容器
$ docker exec -it es bash
# 下载ik分词器
$ ./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.1.1/elasticsearch-analysis-ik-7.1.1.zip
# 退出容器
$ exit -
安装 ik 分词器后重启 Elasticsearch:
docker restart es
-
postman 测试 ik 分词器(注意:把 Content-Type 设置为 application/json )
启动 es-head (可视化界面):
Elasticsearch 5.x后不支持插件,head作为单独服务独立运行。
-
拉取镜像:
docker pull mobz/elasticsearch-head:5
-
启动容器:
docker run -d -p 9100:9100 --name esh elasticsearch-head
-
访问 es-head:
ECS_IP:9100
当你输入 http://192.168.232.128:9200/ 点击连接时,会发现无法连接。是因为前后端分离开发,存在跨域问题,需要在服务端做 CORS 的配置。我们再次进入 Elasticsearch 容器内部,修改
elasticsearch.yml
配置。1
2
3
4
5
6# 进入容器
$ docker exec -it es /bin/bash
[root@7f213e9fb6bb elasticsearch]# vi config/elasticsearch.yml
# 添加如下两条配置,注意冒号后面有空格,保存并退出。
http.cors.enabled: true
http.cors.allow-origin: "*" -
最后退出容器,并重启 Elasticsearch:
docker restart esh
-
再次访问 es-head,就能看到可视化的界面了。
★启动 kibana(可视化界面)
Kibana 是为 Elasticsearch设计的开源分析和可视化平台。可以使用 Kibana 来搜索,查看存储在 Elasticsearch 索引中的数据并与之交互。你可以很容易实现高级的数据分析和可视化,并且以图表的形式展现出来。
是ELK技术栈中的K,也是ES比较主流的可视化界面,也是官方推荐的
Elasticsearch 5.x后不支持插件,跟Elasticsearch head一样,kibana需要作为单独服务独立运行。
-
拉取镜像:
docker pull docker.io/kibana:7.17.2
-
配置文件
1
2
3
4
5
6
7
8
9
10
11mkdir -p ~/dockerdata/elk7/kibana/config/
vi ~/dockerdata/elk7/kibana/config/kibana.yml
#
# ** THIS IS AN AUTO-GENERATED FILE **
#
# Default Kibana configuration for docker target
server.name: kibana
server.host: "0" # 对外访问kibana的地址
elasticsearch.hosts: [ "http://127.0.0.1:9200" ] # elasticsearch的地址
xpack.monitoring.ui.container.elasticsearch.enabled: true -
启动容器:
docker run -d --name=kibana --restart=always -p 5601:5601 -v ~/dockerdata/elk7/kibana/config/kibana.yml:/usr/share/kibana/config/kibana.yml kibana:7.17.2
-
查看日志:
docker logs -f kibana
-
等待30秒,如果出现以下信息,说明启动成功了:
{"type":"log","@timestamp":"2020-08-27T03:00:28Z","tags":["listening","info"],"pid":6,"message":"Server running at http://0:5601"}
-
访问页面:
ECS_IP:5601
就可以看到Welcome to Kibana啦~
Kibana server is not ready yet问题:
docker-compose:
1 | version: '3' |
查看镜像版本:docker-search-tag
1 |
|
然后在终端运行$ ./docker-show-repo-tags.sh elasticsearch
即可获得结果
1 | ... |
Author: Mrli
Link: https://nymrli.top/2022/04/11/总得学点Elasticsearch吧/
Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.