简单介绍一下Elasticsearch全文搜索
ElasticSearch是一个基于Lucene的搜索服务器。通过HTTP使用JSON进行数据索引,用于分布式全文检索,解决人们对于搜索的众多要求。
ES的用途
ES在系统中主要完成商品搜索功能,提高搜索性能。
lucene与elasticsearch(solr)有什么区别?
lucene只是一个提供全文搜索功能类库的核心工具包,而真正使用它还需要一个完善的服务框架搭建起来的应用。好比lucene是类似于jdk,而搜索引擎软件就是tomcat 的。elasticsearch和solr,这两款都是基于lucene的搭建的,可以独立部署启动的搜索引擎服务软件。
基本概念:
cluster集群 | 整个elasticsearch 默认就是集群状态,整个集群是一份完整、互备的数据。 |
node节点 | 集群中的一个节点,一般只一个进程就是一个node |
shard分片 | 分片,即使是一个节点中的数据也会通过hash算法,分成多个片存放,默认是5片。 |
index逻辑数据库 | 相当于rdbms的database, 对于用户来说是一个逻辑数据库,虽然物理上会被分多个shard存放,也可能存放在多个node中。 |
type | 类似于rdbms的table,但是与其说像table,其实更像面向对象中的class , 同一Json的格式的数据集合。 |
document | 类似于rdbms的 row、面向对象里的object |
field | 相当于字段、属性 |
与MySQL对比
利用kibana学习 elasticsearch restful api (DSL)
Kibana 是一个开源分析和可视化平台,可视化操作 Elasticsearch 。Kibana可以用来搜索,查看和与存储在 Elasticsearch 索引中的数据进行交互。可以轻松地进行高级数据分析,并可在各种图表,表格和地图中显示数据。ES提供了基于JSON的query DSL查询语言
es中保存的数据结构
public class Movie { String id; String name; Double doubanScore; List<Actor> actorList; }
public class Actor{ String id; String name; } |
这两个对象如果放在关系型数据库保存,会被拆成2张表,但是elasticsearch是用一个json来表示一个document。所以它保存到es中应该是:
{ “id”:”1”, “name”:”operation red sea”, “doubanScore”:”8.5”, “actorList”:[ {“id”:”1”,”name”:”zhangyi”}, {“id”:”2”,”name”:”haiqing”}, {“id”:”3”,”name”:”zhanghanyu”} ] } |
es 的java 客户端的选择
目前市面上有两类客户端
- 一种是TransportClient 为代表的ES原生客户端,不能执行原生dsl语句必须使用它的Java api方法。
- 一种是以Rest Api为主的missing client,最典型的就是jest。 这种客户端可以直接使用dsl语句拼成的字符串,直接传给服务端,然后返回json字符串再解析。
两种方式各有优劣,但是最近elasticsearch官网,宣布计划在7.0以后的版本中废除TransportClient。以RestClient为主。在官方的RestClient 基础上,进行了简单包装的Jest客户端,就成了首选,而且该客户端也与springboot完美集成。
中文分词:elasticsearch本身自带的中文分词,就是单纯把中文一个字一个字的分开,根本没有词汇的概念。
es使用的问题:
- es大量的写操作会影响es 性能,因为es需要更新索引,而且es不是内存数据库,会做相应的io操作。
- 而且修改某一个值,在高并发情况下会有冲突,造成更新丢失,需要加锁,而es的乐观锁会恶化性能问题。
解决思路:
用redis做精确计数器,redis是内存数据库读写性能都非常快,利用redis的原子性的自增可以解决并发写操作。redis每计100次数(可以被100整除)我们就更新一次es ,这样写操作就被稀释了100倍,这个倍数可以根据业务情况灵活设定。
增量同步索引库
推荐使用MQ(RabbitMQ)原理:使用MQ做增量同步,即当修改数据之后就将此数据发送至MQ,由MQ将此数据同步到ES上
ES索引中使用了IK分词器,你们项目中使用到了分词器的哪种工作模式?
IK分词器,基本可分为两种模式,一种为smart模式,一种为非smart模式。
例如:张三说的确实在理
- smart模式的下分词结果为:张三 | 说的 | 确实 | 在理
- 非smart模式下的分词结果为:张三 | 三 | 说的 | 的确 | 的 | 确实 | 实在 | 在理
区别:
- 可见非smart模式所做的就是将能够分出来的词全部输出;
- smart模式下,IK分词器则会根据内在方法输出一个认为最合理的分词结果,这就涉及到了歧义判断。
怎么分词
使用第三方的分词器IKAnalyzer,会按照中国人用此习惯自动分词。
ES高亮不能显示的问题
前台使用angularJS加载搜索结果,但是发现高亮不能展示。
- 问题原因:angularJS底层使用ajax,异步加载高亮信息返回给页面后,页面没有刷新,就直接显示返回的数据。此时会把所有的数据作为普通的文本数据进行加载。因此就没有高亮的效果。
- 解决方案:使用angularJS过滤器过滤文本数据,此时angularJS过滤器把html文本数据解析为浏览器能识别的html标签。高亮就能展示了。
简单介绍一下Es全文检索在整个系统中的应用,在更新索引库的同时会产生索引碎片,这个碎片是如何处理的?
根据商品的名称,分类,品牌等属性来创建索引进行商品搜索。更新索引库时会先删除索引,然后再重建。而对于删除聚集索引,则会导致对应的非聚集索引重建两次(删除时重建,建立时再重建).直接删除碎片。