spring boot 2.x + elasticsearch+mybatis-plus
阿新 • • 發佈:2018-11-10
第一步引入 maven
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.elasticsearch</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>demo</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.0.2</version> </dependency> <!--mybatis-plus整合--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2 配置檔案
spring: data: elasticsearch: cluster-name: my-application cluster-nodes: 127.0.0.1:9300 properties: path: logs: ./elasticsearch/log data: ./elasticsearch/data datasource: name: oss-service url: jdbc:mysql://localhost:3306/es?useSSL=false&characterEncoding=utf8 username: root password: root # 使用druid資料來源 type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver druid: query-timeout: 2400 filters: stat maxActive: 20 initialSize: 1 maxWait: 60000 minIdle: 1 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: select 'x' testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true maxOpenPreparedStatements: 20
3 config配置
@Configuration
public class ElasticSearchConfig {
@Bean
public ElasticsearchTemplate elasticsearchTemplate(Client client) {
return new ElasticsearchTemplate(client);
}
}
@Configuration @MapperScan("com.elasticsearch.demo.dao") public class MybatisPlusConfig { @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); } /** * SQL執行效率外掛 */ @Bean @Profile({"dev","test"})// 設定 dev test 環境開啟 public PerformanceInterceptor performanceInterceptor() { return new PerformanceInterceptor(); } }
4 java Bean
@Document(indexName = "es", type = "posts", indexStoreType = "fs", shards = 5, replicas = 1, refreshInterval = "-1")
public class Posts {
}
@Document註解裡面的幾個屬性,類比mysql的話是這樣:
index –> DB
type –> Table
Document –> row
@Id註解加上後,在Elasticsearch裡相應於該列就是主鍵了,在查詢時就可以直接用主鍵查詢,後面一篇會講到。其實和mysql非常類似,基本就是一個數據庫。
@Persistent
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Document {
String indexName();//索引庫的名稱,個人建議以專案的名稱命名
String type() default "";//型別,個人建議以實體的名稱命名
short shards() default 5;//預設分割槽數
short replicas() default 1;//每個分割槽預設的備份數
String refreshInterval() default "1s";//重新整理間隔
String indexStoreType() default "fs";//索引檔案儲存型別
}
加上了@Document註解之後,預設情況下這個實體中所有的屬性都會被建立索引、並且分詞。
我們通過@Field註解來進行詳細的指定,如果沒有特殊需求,那麼只需要新增@Document即可。
@Field註解的定義如下:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
@Inherited
public @interface Field {
FieldType type() default FieldType.Auto;#自動檢測屬性的型別
FieldIndex index() default FieldIndex.analyzed;#預設情況下分詞
DateFormat format() default DateFormat.none;
String pattern() default "";
boolean store() default false;#預設情況下不儲存原文
String searchAnalyzer() default "";#指定欄位搜尋時使用的分詞器
String indexAnalyzer() default "";#指定欄位建立索引時指定的分詞器
String[] ignoreFields() default {};#如果某個欄位需要被忽略
boolean includeInParent() default false;
}
@RestController
public class IndexController {
@Autowired
private PostsService postsService;
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
@GetMapping("save")
public String save() {
List<Posts> list = postsService.list(null);
list.stream().forEach(posts -> {
IndexQuery indexQuery = new IndexQueryBuilder().withId(posts.getId() + "").withObject(posts).build();
elasticsearchTemplate.index(indexQuery);
});
return "success";
}
@GetMapping("get")
public Page<Posts> test(String word, @PageableDefault Pageable pageable) {
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(matchQuery("postTitle",word ))
.withPageable(pageable)
.withHighlightFields(new HighlightBuilder.Field("postTitle").preTags("<em>").postTags("</em>"))
.build();
Page<Posts> page = elasticsearchTemplate.queryForPage(searchQuery, Posts.class, new DefaultResultMapper() {
@Override
public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {
List<T> chunk = new ArrayList<>();
for (SearchHit searchHit : searchResponse.getHits()) {
if (searchResponse.getHits().getHits().length <= 0) {
return null;
}
String[] heightFields = {"postTitle"};
Map<String, Object> entityMap = searchHit.getSource();
for (String highName : heightFields) {
Text text[] = searchHit.getHighlightFields().get(highName).fragments();
if (text.length > 0) {
String highValue = searchHit.getHighlightFields().get(highName).fragments()[0].toString();
entityMap.put(highName, highValue);
}
}
try {
T t = getEntityMapper().mapToObject(searchHit.getSourceAsString(), aClass);
Field postTitle = aClass.getDeclaredField("postTitle");
postTitle.setAccessible(true);
postTitle.set(t,entityMap.get("postTitle"));
// Field postContent = aClass.getDeclaredField("postContent");
// postContent.setAccessible(true);
// postContent.set(t,entityMap.get("postContent"));
chunk.add(t);
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
// chunk.add((Posts) PropertyHelper.getFansheObj(
// Posts.class, entityMap));
}
return new AggregatedPageImpl(chunk);
}
});
return page;
}
}