背景
现在很多互联网应用都提供了站内搜索功能,例如:淘宝可以根据商品名称搜索商品、百度可以根据输入的关键词搜索相关的网页、微博可以通过关键词搜索相关微博。那么这个功能该如何实现呢?
通过关系型数据库的模糊查询实现(like ‘%%’)。例如:
select * from product where name like '%苹果手机%'
但是模糊查询存在以下2点问题
- 使用全模糊无法走索引:当数据量很大的时候查询性能低下
- 无法分词:上述查询只会查询出包含“苹果手机”字段的结果集,无法查询出“苹果1手机”。如果我们错将关键词打成“苹手机”那么也查询不出相关结果
ElasticSearch功能
- 分布式的搜索引擎和数据分析引擎
搜索:站内搜索
数据分析:微博热搜、热门商品等
- 全文检索、结构化搜索,数据分析
全文检索:类似于关系型数据库的全模糊查询
结构化检索:类似于关系型数据库的等值查询
部分匹配、自动完成、搜索纠错、搜索推荐等
数据分析:我们分析每一个商品分类下有多少个商品
- 对海量数据近实时处理(PB级数据量,延迟秒级)
分布式:es可以将数据在多台机器上存储和检索
近实时:检索和分析数据基本在秒级别
倒排索引&全文检索
ElasticSearch是如何解决关系型数据库的全模糊效率低和无法分词的问题呢?
倒排索引
例如:商品表有id和name2个字段。
| id | name |
|---|---|
| 1 | 苹果手机 |
| 2 | 三星手机 |
| 3 | 华为手机 |
搜索引擎会通过分词器将表中的数据进行分词并记录对应的关键词和id
| 关键词 | ids |
|---|---|
| 手机 | 1,2,3,4 |
| 苹果 | 1 |
| 三星 | 2 |
| 华为 | 3 |
全文检索
当我们通过关键词“苹手机”进行检索时,搜索引擎通过先将关键词进行分词后得到“苹”、“手机”,接着通过倒排索引后的结果集分别对“苹”和“手机”进行检索,获取到对应的记录id
ElasticSearch不适用场景
既然ElasticSearch能存储海量数据(mysql单表最好不超过2000W)并且查询性能又好,那么是不是可以完全替代关系型数据库呢?
不能。关系型数据库主要是有ACID特性的,而ES在一致性方面有所欠缺(没有事务),所以对于有强一致性要求的场景使用ES是不适合的。
总结
- 可以作为一个大型分布式集群(数百台服务器)技术,处理PB级数据
- Elasticsearch不是什么新技术,主要是将全文检索、数据分析以及分布式技术,合并在了一起,才形成了独一无二的ES;lucene(全文检索),商用的数据分析软件,分布式数据库(mycat)
- 对用户而言,是开箱即用的,非常简单
- 没有事务支持,是对关系型数据库的补充(不是替代)
