主要内容
首先一起了解elasticSearch,然后结合springData,看看如何使用elasticSearch。
demo
GitHub - chlInGithub/esdemohttps://github.com/chlInGithub/esdemo
介绍篇
what
全文搜索与分析引擎,可以存储、搜索、分析海量数据,速度近乎实时。
输入:document和索引
es对json形式的复杂文档进行分布式存贮。当文档存储时,会进行索引,达到近实时的全文搜索。
es采用倒排索引以支持快速的全文搜索。倒排索引首先列举文档中独特的单词,然后识别含有该单词的所有文档。
一个索引可以视为文档的优化集合,一个文档由多个field(存储数据的k-v对)组成。es对field中的所有数据进行索引,每一个被索引的field对应一个独特的优化的数据结构。例如文本field存储到反向索引,数字型和地理坐标存储到BKD树。聚合每个field的数据结构,然后返回搜索结果,这样使得es查询很快。
文档被索引时,不需要明确指定文档中各种field如何控制,即无模式。dynamic mapping开启后,es可以自动发现和添加新的field。这种行为,使得索引和探索数据变得更简单。
也可以定义dynamic mapping的规则和明确定义如何存储和索引field。价值在于:
- 区分全文字符串field和精确值字符串
- 特定语言文本的分析
- 为部分匹配进行字段优化
- 自定义的时间格式
- 指定数据类型,如geo_point、geo_shape
出于不同目的,需要对同一个field使用不同的方式进行索引。
输出:搜索与分析
可以使用es进行文档存储和文档检索,但真正强大之处在于可以方便的使用apache lucene检索引擎库的检索套件。
es提供了搜索和数据分析能力。
- 提供了简单的RestApi,用于管理集群、索引、查询。
- es的聚合能力可以构建数据的复杂汇总,以便察觉指标、趋势、模型
扩展性
集群能力,可以通过添加node的方式提升能力,es自动进行数据分布式,查询所有可用node中的文档。
一个索引代表了多个物理分片shard的逻辑分组,而每个分片又是一个自包含的索引。一个索引的所有文档被放到了多个分片中,然后在集群中对分片进行分布式存储,而是是冗余存储的。
分片分为两种:主分片和复制分片。一个索引中的每个文档都属于一个主分片。复制分片是对主分片的复制。
配置
涉及3个文件
- elasticsearch.yml
- jvm.options
- log4j2.properties
pipeline
在构建索引之前,对文档进行转换,对转换后的新文档构建索引。
使用篇
spring提供es组件(Spring Data ElasticSearch),这样我们可以方便的使用es了。
由Elasticsearch client与es进行连接,spring提供了更高层的抽象 Elasticsearch Operations和Repositories.
maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
使用过程的关注点
- 配置器
- 数据资源库
- 转换器
- 域对象
接下来分别详细介绍。
配置器
AbstractElasticsearchConfiguration | 作为autoconfig的配置器,继承该类以提供RestHighLevelClient、添加转换器。 |
ClientConfiguration | 针对es client的配置 |
RestHighLevelClient | 对RestClient进行了包装,提供构建请求和读取结果的能力。 |
数据资源库
@EnableElasticsearchRepositories | 自动扫描资源库 |
CrudRepository | 数据资源库,类似dao层 |
接口名称规则 | 通过接口名称指定搜索条件 |
通过接口名称指定搜索条件,适用于count、delete、find,以下以find为例。以下为规则图示:
很重要的一个场景,分页如何搞呢?参数Pageable。
着重说明:规则可组合。
实例代码
public interface PersonRepository extends CrudRepository<Person, String> {
/**
* name模糊查询,age倒序
* @param name
* @return
*/
List<Person> findByNameLikeOrderByAgeDesc(String name);
/**
* name模糊查询 且 age上限,age倒序
* @return
*/
List<Person> findByNameLikeAndAgeLessThanOrderByAgeDesc(String name, int age);
/**
* count条件
* @return
*/
int countByAgeIsLessThan(int age);
/**
* delete条件
*/
void deleteByName(String name);
/**
* 分页查询
* @param name
* @param pageable
* @return
*/
List<Person> findByNameLike(String name, Pageable pageable);
/**
* 取top N 条记录
* @param name
* @return
*/
List<Person> findTop3ByNameLikeOrderByAge(String name);
// ...
}
转换器
Converter | 需要自定义实现类 |
@WritingConverter | 如域对象转换为map |
@ReadingConverter | 如map转换为域对象 |
域对象
@Document | 表明序列化到es的域对象。默认,启动时,自动创建索引。 |
@Field @Id |
具体使用代码请见上文demo。
参考文档