Skip to content

Instantly share code, notes, and snippets.

@superborges
Last active August 22, 2019 15:19
Show Gist options
  • Save superborges/4b3554c3e33422c74a291cf0276b5b61 to your computer and use it in GitHub Desktop.
Save superborges/4b3554c3e33422c74a291cf0276b5b61 to your computer and use it in GitHub Desktop.
Spring Data ES 源码研究

SDE源码(git-master)

源码目录结构

分为五个

  1. annotations:各种注解,主要用到的是@Document 和 @Field
  2. client: NodeClient 和 TransportClinet,一般都是用后者,前者是个玩具啊
  3. config: 还不知道是干啥的
  4. core: 核心包,正准备研究是干啥的
  5. repository: 从本质上,目前不知道是干啥的

模块化研究

Core包

Query 接口

  1. Query 有两个直接子接口 SeachQuery 和抽象类 AbstractQuery,但两者有个共同的实现类 NativeSearchQuery,感觉这个类应该有点叼。后面重点关注下。
  2. SearchQuery里的Facet 被干掉了,暴露了Query和Filter的builder。 Aggregations我见过很多次了,没有彻底理解。这次得弄明白。同时暴露了HightlightFileds,ScriptFields,IndexBoost之类的细节,后面再说。
  3. 抽象类AbstractQuery基本上实现了Query的一堆Getter和Setter. (我屮艸芔茻,没有一个方法是Abstract的,理论上已经实现了个Query接口。)
  4. AbstractQuery的一个子类,StringQuery,增加了一个属性,Source。打酱油的,可以忽略。
  5. AbstractQuery的子类:CriteriaQuery,非常重要的一个类。封装一个Fluent API Style的Criteria,能做 where, and, or, is, contains, startsWith, endsWith, not, contains, expression …… 等各种常用操作。

Criteria类

  1. 构造函数管理的对象是Field(只有一个属性name),还会有个arraylist的criteriachain。
  2. OrCriteria继承了Criteria,区别是 override 了 ConjunctionOperator
  3. Criteria的contains,startsWith, endsWith等, 参数不接受 空格
  4. not方法,是将negating参数置为true
  5. Criteria还支持Location GeoBox Bounding Box 查询(厉害,经纬度的查询)
  6. CriteriaEntry的实现原理是转换成原生的ES Query,转换介质是枚举变量
public enum OperationKey {
   EQUALS, CONTAINS, STARTS_WITH, ENDS_WITH, EXPRESSION, BETWEEN, FUZZY, IN, NOT_IN, WITHIN, BBOX, NEAR, LESS, LESS_EQUAL, GREATER, GREATER_EQUAL;
}
  1. boost 是干啥的? postive hit with given factor
  2. filter是干啥的? 用在Geo Location的查询中

CriteriaQuery类

封装了Criteria,没啥好说的。

NativeSearchQuery

暂时还不知道干啥的以及是怎么用的?(但实际 业务里 用的就是它。尴尬。)

它封装了ES里的QueryBuilder和SortBuilder,后面看看它怎么用

ElasticSearchTemplate

继承自ElasticsearchOperations接口

ElasticsearchOperations
  1. 索引 的 创建
  2. Mapping的创建(对indexName(database)和 Type (table)的Mapping,目前不知道是干啥的
  3. 获取IndexName的Setting (数据格式是一个map)
  4. 常规的QueryForObject, QueryForPage等操作
  5. count, multiGet
  6. update, index, delete
  7. scan, scroll
  8. 几个特殊的Query:MoreLikeThisQuery AliasQuery
EST的实现

封装了一个ES的Client, 能完成index,mapping,setting相关的request请求

queryForPage实现
  1. 创建Query和Filter两个QueryBuilder(ES的),其中Query用于普通字段的查询,Filter用于Geo Location数据的查询。
  2. Query-QuerBuidler里是根据CriteriaEntry和前面列举的枚举变量OperationKey转换成ES原生的queryStringQuery, rangeQuery, fuzzyQuery, boolQuery
  3. 然后用一个BoolQueryBudiler(ES原生)把第2步生成的全部Query串起来。
  4. 辅助设置一下参数,例如SourceFilter,Pageable(转换成ES原生的起始点选择),sort, minscore之类的。
  5. 有处理一个script Field (ES里原生的script, 不知道是干啥的)
  6. 还有MultiGetResponse, 不知道是干啥的
  7. 也有直接使用SearchQuery(SDE)作为参数,而用SearchResponse(ES)作为返回的Query方法
  8. AggregatedResponse 不知道干啥的。
Scan实现
  1. 可以用来完成大数据量的Scan && Scroll
  2. 暂时用不到,但数据规模到一定规模时,应该有用。(观察下Jest里的实现)

结论

  1. 结合Spring和注解,在POJO上利用Document和Filed注解,然后结合Repository风格的Dao,可以非常有效的创建索引。 (save方法,推荐这么使用)
  2. 一些简单的、常规的查询,推荐使用CriteriaQuery,配合EST
  3. 复杂的、自定义的、得分排序等等高阶查询,需要是用SearchQuery集成ES原生的各种TermQuery、RangeQuery等。(所以还是要认真学下ES的原生JAVA API

TODO

看下SDE的TEST目录

  1. 看看专业的、生产可用的项目是如何写单元测试的
  2. 看看SDE还有什么高级使用方法。处理本文档中大量的“不知道是干啥的
  3. SDE的测试里用到了hamcrest,(也不知道是干啥的
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment