background
最近在学习项目的时候会遇到搜索和推荐相关的知识内容, 刚好借此机会好好学习一下搜索和推荐部分的内容, 一次性打通这个整体的技术栈。
content
search
elasticSearch 原理和部署
搜索的原理
- es是什么: 是一个中间件, 运行在一个进程节点中, 对外通过http接口提供搜索服务, 对内提供数据的存储。
- es的名词定义: 这里要注意es索引是指数据库,不是mysql里面那个索引, es中每个词都可以做索引(动词的意思)。

- 分词 : 搜索引擎第一步将用户的输入进行分词,最简单的就是按照空格分词。 一句话分成几个词之后,用这几个分词去搜索es存储的索引, es中存储的索引是通过连接mysql实时构建倒排索引进行创建的, 这些索引会和搜索进行匹配, 这种方式明显要比mysql的like搜索更为合理。
- 倒排索引 : 倒排索引是通过关键词后面连接对应搜索的文档, 而正排是文档后连接关键词, 很明显倒排索引在关键词搜索的时候非常方便, 当我们搜索小明时候, 就直接去包含小明的文档中去找就行。 | 到这我们不难理解为啥es中的index是数据库了, 一个index存储了很多包含的documment

- TF/IDF打分机制 : 如果搜索的关键词中有多个文档命中, 具体选谁就要看这个TF/IDF打分 。 TF是看文档中词的频率, DF是看文档评率, 因此IDF是反文档率, 代表这个词的区分度。最后我们用TF * IDF就能使用一个频率较高并且在文档之间比较独特的倒排索引,效果很好。 | 此外还需要加归一化, 避免单个词过于影响权重。
es + kibana下载安装
- 这个类似可以参照zookeeper, 大致是一样的。
- kibana 启动之后连接es服务器, 然后就可以通过web界面进行操作。

es 分布式原理与配置
在这我们讲一下为什么es能够支持海量数据的访问, 主要是主从和分片, 两个机制。
- primary shard分片: 因为索引后面可能有很多文档, 因此需要分片让一个索引的内容可以存储到不同的节点中,不然一个节点扛不住。 分片分为主分片 (primary shard) 以及从分片 (replica shard)。主分片会被尽可能平均地 (rebalance) 分配在不同的节点上(例如你有 2 个节点,4 个主分片(不考虑备份),那么每个节点会分到 2 个分片,后来你增加了 2 个节点,那么你这 4 个节点上都会有 1 个分片,这个过程叫 relocation,ES 感知后自动完成)。
- 主从节点replica : 主要就是为了防止数据丢失, 和zk是差不多的。
- 注意主从和分片的概念不一样, 分片是index单元的, 主从是节点的。 不过集群的master知道所有的从节点里面分片的位置。 | 一般读都是在从节点中操作分片, 只有写的时候才去操作主节点的数据。

elasticSearch基础语法
索引的创建、更新和删除
- 我们可以在employee的索引库中创建第一个文档,编号为1, 然后放入数据。

- 使用get去获取数据。

3. 其他的一些基本操作。

- 其他等等都是直接看介绍就会的。
索引的复杂查询
-
分页查询而且不带条件
-
带条件查询, 可以看到即使把兄弟搞成兄长,也能匹配到, 因为这里分词是按照字去分的。

-
filter,match , 聚合方式等高级 查询。
elasticSearch高级语法
- analyze 分析过程(也就是分词器)
- 我们给出一个具体的查询代码来看看搜索引擎的分词器状态。 | 可以看到我们用eat是查不到的, 因此我们用analyze分词器看看这些分词是没有eating, 因此命中不了。

这样看起来感觉es还是有点傻, 其实他还是有升级的。 可以指定使用英文的分词器去分词 , 它能够用eat搜eating, 而且会将一些an等介词给过滤,去除单复数词干只保留词干(例如 apple 索引是appl, eating 索引是eat)。 我们可以发现搜索引擎的强大之处。

elasticSearch高级用法
实际应用中索引建立和数据导入的过程
- 我们以tmdb数据集进行实际的操作来跟着学习, 他的数据质量还是非常高的。
- 根据数据我们定义一个move的数据库,根据实际的数据创建索引结构。 | 使用开源的csv to es的 java_web项目导入到自己的es中 |
Query 高级用法
- match查询
- and 和or的逻辑
- 最小命中数量设置
- 短语查询
- 多字段查询 : 通过多个字段类型综合去查。
- TF和IDF打分 加归一化加权。 | BM25 是用来解决词频问题, 将太过高频率的词占比放小, 例如1 和10 差距很大, 但是10 和50 差距不是很大 |
- 通过explain参数, 来看看我们单字段打分的加权。
- 多字段打分的计算机制 : 直接取最大的。
- 优化多字段查询 : 可以将关键字段权重加强 | 也可以当多字段都命中的情况下加强tie_breaker。
- bool进行优化, 命中越多打分越高
- 通过*.filed去改变命中词之间的规则。
- 多条件过滤
- 带条件设置排序规则
- 查全率和查准率 : 这个所有正确数量的定义是人为定义的, 而且查全率和查准率是冲突的 例如你搜苹果,追求查全率会出来水果, 追求查准率就只出iphone。 因此我们需要去平衡这两个率, 然后通过排序分数显示出来 。
- 自定义分数 : function_score, 他会让我们设置水果权重, 再加上设置手机权重, 最后得到一个包含水果和手机的得分排序。
summary
reference