spring elasticsearch 按条件删除_实战:项目数据源转为Elasticsearch
原本項(xiàng)目是基于MYSQL的,現(xiàn)因需求將其轉(zhuǎn)換為MYSQL+Elasticsearch,MYSQL的ORM使用的是Spring Data Jpa,Mybatis的轉(zhuǎn)換與其類似,有人看再更
先看原項(xiàng)目
原項(xiàng)目的DAO層
@Repository public interface UserRepository extends JpaRepository<User, Long> {Optional<User> findOneByActivationKey(String activationKey);List<User> findAllByActivatedIsFalseAndCreatedDateBefore(Instant dateTime);Optional<User> findOneByResetKey(String resetKey);Optional<User> findOneByEmailIgnoreCase(String email);Optional<User> findOneByLogin(String login);@EntityGraph(attributePaths = "authorities")Optional<User> findOneWithAuthoritiesById(Long id);@EntityGraph(attributePaths = "authorities")Optional<User> findOneWithAuthoritiesByLogin(String login);@EntityGraph(attributePaths = "authorities")Optional<User> findOneWithAuthoritiesByEmail(String email);Page<User> findAllByLoginNot(Pageable pageable, String login); }原項(xiàng)目的DTO
1.User.java
@Entity @Table(name = "user") public class User implements Serializable {private static final long serialVersionUID = 1L;@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@NotNull@Pattern(regexp = Constants.LOGIN_REGEX)@Size(min = 1, max = 50)@Column(length = 50, unique = true, nullable = false)private String login;@JsonIgnore@NotNull@Size(min = 60, max = 60)@Column(name = "password_hash", length = 60, nullable = false)private String password;@Email@Size(min = 5, max = 254)@Column(length = 254, unique = true)private String email;@NotNull@Column(nullable = false)private boolean activated = false;@Column(name = "reset_date")private Instant resetDate = null;@JsonIgnore@ManyToMany@JoinTable(name = "jhi_user_authority",joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},inverseJoinColumns = {@JoinColumn(name = "authority_name", referencedColumnName = "name")})@BatchSize(size = 20)private Set<Authority> authorities = new HashSet<>();//... }2.Authority.java
@Entity @Table(name = "jhi_authority") public class Authority implements Serializable {private static final long serialVersionUID = 1L;@NotNull@Size(max = 50)@Id@Column(length = 50)private String name; }可以看出原項(xiàng)目使用Spring data + hibernate 作為ORM,規(guī)范的使用其格式進(jìn)行自動(dòng)生成SQL語句
接下來就是轉(zhuǎn)換成elasticsearch的時(shí)候了
這里我不采用elasticsearch官網(wǎng)的client依賴包而是spring-data-elasticsearch,原因如下:
①首先先配置elasticsearch
pom.xml加入
<dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-elasticsearch</artifactId></dependency>若你是spring boot項(xiàng)目,則在 application.yml 或者 application.properties 加入
spring: data:elasticsearch:cluster-nodes: localhost:9300若你是普通spring項(xiàng)目則看
Spring Data Elasticsearch?docs.spring.io進(jìn)行配置
②改造DTO
把原有的spring data 注解刪除掉
然后替換成elasticsearch的注解
@Document(indexName = "user", type = "doc") public class User {//這里的instant jackson無法直接從string轉(zhuǎn)換為instant,需要編寫個(gè)編解碼類@JsonSerialize(using = InstantJacksonSerializer.class)@JsonDeserialize(using = InstantJacksonDeserialize.class)private Instant createdDate;private String createdBy;private boolean activated;//原項(xiàng)目Id,是使用Long類型,這里不改,但elasticsearch的話推薦使用String作為Id,因?yàn)樽詣?dòng)創(chuàng)建id的時(shí)候?yàn)殡S機(jī)字符串@Idprivate Long id;private Set<Authority> authorities;private String login;private String email;//... }可以看到,我除了刪除了原項(xiàng)目的注解外,DTO就只有添加了 @Document(indexName = user", type = "doc") ,Instant是原項(xiàng)目使用的,如果是用Date的話則使用 @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
③改造DAO層
先看改造后的
public interface UserRepository extends ElasticsearchRepository<User, Long> {Optional<User> findOneByActivationKey(String activationKey);List<User> findAllByActivatedIsFalseAndCreatedDateBefore(Instant dateTime);Optional<User> findOneByResetKey(String resetKey);Optional<User> findOneByEmailIgnoreCase(String email);Optional<User> findOneByLogin(String login);Optional<User> findOneByEmail(String email);Page<User> findAllByLoginNot(Pageable pageable, String login);}將UserRepository 改為繼承ElasticsearchRepository<User, Long> ,其中第一個(gè)參數(shù)為DTO,第二個(gè)參數(shù)為Id,把連表的with給去掉即可(IDEA中用shift+F6可以很方便的),若你需要特殊查詢,可以使用
@Query("{"bool" : {"must" : {"field" : {"name" : "?0"}}}}")Page<Book> findByName(String name,Pageable pageable);④關(guān)于join的問題
Elasticsearch是不支持join操作的,可以有以下幾種解決方案
在本項(xiàng)目中我用的是方案一,再復(fù)雜點(diǎn)的情況之后再考慮
⑤關(guān)于遇到的坑
//MYSQL@Size(max = 50)@Column(name = "first_name", length = 50)private String firstName;//Elasticsearchprivate String firstName;MYSQL數(shù)據(jù)庫里儲(chǔ)存的字段名都是first_name這樣以下劃線作為分詞的,而spring data Elasticsearch 我并沒有找到轉(zhuǎn)義的相應(yīng)注解。。。。如果有人知道麻煩告訴下
我的解決方案:
在導(dǎo)入數(shù)據(jù)源的時(shí)候,把其改為駝峰法的結(jié)構(gòu)
⑥數(shù)據(jù)導(dǎo)入
我使用的是logstash,還有其他框架可以使用,按需求自己決定吧
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的spring elasticsearch 按条件删除_实战:项目数据源转为Elasticsearch的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 虚拟主机选择php版本,虚拟主机的php
- 下一篇: c语言tmplink,为了便于阅读,偿试