spring elasticsearch 按条件删除_实战:项目数据源转为Elasticsearch
原本項目是基于MYSQL的,現因需求將其轉換為MYSQL+Elasticsearch,MYSQL的ORM使用的是Spring Data Jpa,Mybatis的轉換與其類似,有人看再更
先看原項目
原項目的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); }原項目的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; }可以看出原項目使用Spring data + hibernate 作為ORM,規范的使用其格式進行自動生成SQL語句
接下來就是轉換成elasticsearch的時候了
這里我不采用elasticsearch官網的client依賴包而是spring-data-elasticsearch,原因如下:
①首先先配置elasticsearch
pom.xml加入
<dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-elasticsearch</artifactId></dependency>若你是spring boot項目,則在 application.yml 或者 application.properties 加入
spring: data:elasticsearch:cluster-nodes: localhost:9300若你是普通spring項目則看
Spring Data Elasticsearch?docs.spring.io進行配置
②改造DTO
把原有的spring data 注解刪除掉
然后替換成elasticsearch的注解
@Document(indexName = "user", type = "doc") public class User {//這里的instant jackson無法直接從string轉換為instant,需要編寫個編解碼類@JsonSerialize(using = InstantJacksonSerializer.class)@JsonDeserialize(using = InstantJacksonDeserialize.class)private Instant createdDate;private String createdBy;private boolean activated;//原項目Id,是使用Long類型,這里不改,但elasticsearch的話推薦使用String作為Id,因為自動創建id的時候為隨機字符串@Idprivate Long id;private Set<Authority> authorities;private String login;private String email;//... }可以看到,我除了刪除了原項目的注解外,DTO就只有添加了 @Document(indexName = user", type = "doc") ,Instant是原項目使用的,如果是用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> ,其中第一個參數為DTO,第二個參數為Id,把連表的with給去掉即可(IDEA中用shift+F6可以很方便的),若你需要特殊查詢,可以使用
@Query("{"bool" : {"must" : {"field" : {"name" : "?0"}}}}")Page<Book> findByName(String name,Pageable pageable);④關于join的問題
Elasticsearch是不支持join操作的,可以有以下幾種解決方案
在本項目中我用的是方案一,再復雜點的情況之后再考慮
⑤關于遇到的坑
//MYSQL@Size(max = 50)@Column(name = "first_name", length = 50)private String firstName;//Elasticsearchprivate String firstName;MYSQL數據庫里儲存的字段名都是first_name這樣以下劃線作為分詞的,而spring data Elasticsearch 我并沒有找到轉義的相應注解。。。。如果有人知道麻煩告訴下
我的解決方案:
在導入數據源的時候,把其改為駝峰法的結構
⑥數據導入
我使用的是logstash,還有其他框架可以使用,按需求自己決定吧
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的spring elasticsearch 按条件删除_实战:项目数据源转为Elasticsearch的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 虚拟主机选择php版本,虚拟主机的php
- 下一篇: c语言tmplink,为了便于阅读,偿试