最近需要迁移以前的ElasticSearch相关代码到现在的项目,迁移过来后发现很多类方法接口要么显示过时要么直接没呢,我想是因为现在项目的SpringBoot的版本比之前要新很多,然后又不想还是用原来老版本的Spring Data ElasticSearch,所以就升级迁移新版本。
ElasticSearch配置文件
3.1.3版本
TransportClient客户端现在官方已经不推荐,而且表示以后会弃用它
@Configuration
public class ElasticsearchConfig {
@Value("${elasticsearch.cluster}")
private String cluster;
@Value("${elasticsearch.ip}")
private String ip;
@Value("${elasticsearch.port}")
private int port;
@Bean
public Client client() {
Settings settings = Settings.builder().put("cluster.name", cluster).build();
TransportClient client = new PreBuiltTransportClient(settings);
try {
client.addTransportAddress(new TransportAddress(InetAddress.getByName(ip), port));
} catch (UnknownHostException e) {
e.printStackTrace();
}
return client;
}
}
4.3.3版本
这里用的是官方推荐的RestHighLevelClient客户端,将会替代TransportClient
@Configuration
public class ElasticsearchConfig {
@Value("${elasticsearch.cluster}")
private String cluster;
@Value("${elasticsearch.ip}")
private String ip;
@Value("${elasticsearch.port}")
private int port;
@Bean
public RestHighLevelClient client() {
ClientConfiguration clientConfiguration = null;
try {
clientConfiguration = ClientConfiguration.builder()
.connectedTo(ip+":"+port)
.build();
}catch (Exception e){
e.printStackTrace();
}
return RestClients.create(clientConfiguration).rest();
}
}
@Document
3.1.3的type在4.3.3中已去掉
3.1.3版本
@Persistent
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Document {
String indexName();
String type() default "";
boolean useServerConfiguration() default false;
short shards() default 5;
short replicas() default 1;
String refreshInterval() default "1s";
String indexStoreType() default "fs";
boolean createIndex() default true;
}
4.3.3
@Persistent
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
public @interface Document {
/**
* Name of the Elasticsearch index.
* <ul>
* <li>Lowercase only</li>
* <li>Cannot include \, /, *, ?, ", >, <, |, ` ` (space character), ,, #</li>
* <li>Cannot start with -, _, +</li>
* <li>Cannot be . or ..</li>
* <li>Cannot be longer than 255 bytes (note it is bytes, so multi-byte characters will count towards the 255 limit
* faster)</li>
* </ul>
*/
String indexName();
/**
* Use server-side settings when creating the index.
*
* @deprecated since 4.2, use the {@link Setting} annotation to configure settings
*/
@Deprecated
boolean useServerConfiguration() default false;
/**
* Number of shards for the index {@link #indexName()}. Used for index creation. <br/>
* With version 4.0, the default value is changed from 5 to 1 to reflect the change in the default settings of
* Elasticsearch which changed to 1 as well in Elasticsearch 7.0.
* ComposableAnnotationsUnitTest.documentAnnotationShouldBeComposable:60
*
* @deprecated since 4.2, use the {@link Setting} annotation to configure settings
*/
@Deprecated
short shards() default 1;
/**
* Number of replicas for the index {@link #indexName()}. Used for index creation.
*
* @deprecated since 4.2, use the {@link Setting} annotation to configure settings
*/
@Deprecated
short replicas() default 1;
/**
* Refresh interval for the index {@link #indexName()}. Used for index creation.
*
* @deprecated since 4.2, use the {@link Setting} annotation to configure settings
*/
@Deprecated
String refreshInterval() default "1s";
/**
* Index storage type for the index {@link #indexName()}. Used for index creation.
*
* @deprecated since 4.2, use the {@link Setting} annotation to configure settings
*/
@Deprecated
String indexStoreType() default "fs";
/**
* Configuration whether to create an index on repository bootstrapping.
*/
boolean createIndex() default true;
/**
* Configuration of version management.
*/
VersionType versionType() default VersionType.EXTERNAL;
/**
* Defines if type hints should be written. {@see WriteTypeHint}.
*
* @since 4.3
*/
WriteTypeHint writeTypeHint() default WriteTypeHint.DEFAULT;
/**
* Controls how Elasticsearch dynamically adds fields to the document.
*
* @since 4.3
*/
Dynamic dynamic() default Dynamic.INHERIT;
/**
* @since 4.3
*/
enum VersionType {
INTERNAL, EXTERNAL, EXTERNAL_GTE
}
}
ElasticsearchTemplate已过时
4.3.3中ElasticsearchTemplate已显示过时,而且在4.3.3中ElasticsearchTemplate的
queryForPage方法已删除,SearchResultMapper、AggregatedPage在4.3.3中也已删除
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
官方现在推荐的是ElasticsearchRestTemplate
@Autowired
private ElasticsearchRestTemplate elasticsearchTemplate;
高亮查询
3.1.3
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
......
// 构建查询
NativeSearchQueryBuilder searchQuery = new NativeSearchQueryBuilder();
// 组合查询,boost即为权重,数值越大,权重越大
QueryBuilder queryBuilder = QueryBuilders.boolQuery()
.should(QueryBuilders.multiMatchQuery(value, "title").boost(2))
.should(QueryBuilders.multiMatchQuery((value, "content").boost(1));
searchQuery.withQuery(queryBuilder);
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
searchQuery.withFilter(boolQueryBuilder.must(QueryBuilders.termQuery("desc", desc)));
// 高亮设置
List<String> highlightFields = new ArrayList<String>();
highlightFields.add("title");
highlightFields.add("content");
Field[] fields = new Field[highlightFields.size()];
for (int x = 0; x < highlightFields.size(); x++) {
fields[x] = new HighlightBuilder.Field(highlightFields.get(x)).preTags("<font color='#f73131'>")
.postTags("</font>");
}
searchQuery.withHighlightFields(fields);
// 分页设置
searchQuery.withPageable(pageable);
AggregatedPage<EsContent> page = elasticsearchTemplate.queryForPage(searchQuery.build(),
EsContent.class, new SearchResultMapper() {
@Override
public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz,
Pageable pageable) {
// 获取高亮搜索数据
List<EsContent> list = new ArrayList<EsContent>();
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits) {
EsContent data = new EsContent();
// 公共字段
data.setId(new Double(searchHit.getId()).longValue());
data.setTitle(String.valueOf(searchHit.getSourceAsMap().get("title")));
String content = String.valueOf(searchHit.getSourceAsMap().get("content"));
data.setContent(content);
data.setDesc(String.valueOf(searchHit.getSourceAsMap().get("desc")));
try {
data.setDate(DateUtil.date_sdf
.parse(String.valueOf(searchHit.getSourceAsMap().get("date"))));
} catch (ParseException e1) {
e1.printStackTrace();
}
HighlightField titleHh = searchHit.getHighlightFields().get("title");
if (titleHh != null) {
data.setTitle(titleHh.fragments()[0].toString());
}
HighlightField contentHf = searchHit.getHighlightFields().get("content");
if (contentHf != null) {
String contentHfStr = contentHf.fragments()[0].toString();
data.setcontent(contentHfStr);
}
data.setScoreShow(String.valueOf(searchHit.getScore()));
list.add(data);
}
if (list.size() > 0) {
AggregatedPage<T> result = new AggregatedPageImpl<T>((List<T>) list, pageable,
response.getHits().getTotalHits());
return result;
}
return null;
}
});
4.3.3
@Autowired
private ElasticsearchRestTemplate elasticsearchTemplate;
......
// 组合查询,boost即为权重,数值越大,权重越大
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
.should(QueryBuilders.multiMatchQuery(value, "title").boost(2))
.should(QueryBuilders.multiMatchQuery(value, "content").boost(1));
// 高亮设置
List<String> highlightFields = new ArrayList<String>();
highlightFields.add("title");
highlightFields.add("content");
HighlightBuilder.Field[] fields = new HighlightBuilder.Field[highlightFields.size()];
for (int x = 0; x < highlightFields.size(); x++) {
fields[x] = new HighlightBuilder.Field(highlightFields.get(x)).preTags("<font color='#f73131'>")
.postTags("</font>");
}
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
//构建高亮查询
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(queryBuilder)
.withHighlightFields(fields)
.withHighlightBuilder(new HighlightBuilder().preTags("<span style='color:red'>").postTags("</span>"))
// 分页设置
.withPageable(pageable)
.withFilter(boolQueryBuilder.must(QueryBuilders.termQuery("desc", desc)))
.build();
//查询
SearchHits<EsContent> search = elasticsearchTemplate.search(searchQuery, EsContent.class);
//得到查询返回的内容
List<SearchHit<EsContent>> searchHits = search.getSearchHits();
//设置一个最后需要返回的实体类集合
List<EsContent> lists = new ArrayList<>();
//遍历返回的内容进行处理
for (SearchHit<EsContent> searchHit : searchHits) {
//高亮的内容
Map<String, List<String>> highlightdatas = searchHit.getHighlightFields();
EsContent data = new EsContent();
// 公共字段
data.setId(new Double(searchHit.getId()).longValue());
data.setTitle(String.valueOf(searchHit.getContent().getTitle()));
String content = String.valueOf(searchHit.getContent().getContent());
if (content.length() > 300) {
content = content.substring(0, 300) + "...";
}
data.setContent(content);
data.setDesc(String.valueOf(searchHit.getContent().getDesc()));
try {
if(searchHit.getContent().getDate()!=null){
data.setContentDate(DateUtil.date_sdf
.parse(String.valueOf(searchHit.getContent().getDate())));
}
} catch (ParseException e1) {
e1.printStackTrace();
}
List<String> title = highlightdatas.get("title");
if (title != null) {
data.setTitle(title.get(0));
}
List<String> content1 = highlightdatas.get("content");
if (content1 != null) {
String contentHfStr = content1.get(0);
data.setContent(contentHfStr);
}
data.setScoreShow(String.valueOf(searchHit.getScore()));
lists.add(data);
}