背景描述:
系统搜索推广活动,由以前的数据库模糊匹配的方式切换为搜索引擎的方式,选用的内容以ElasticSearch为主,本篇文档主要记录了使用ES进行单节点部署以及开发ES搜索的代码讲解,最后会上传部分代码供大家参考。
系统环境:
部署环境:CentOS 6.7 + JDK 1.7 + ElasticSearch 2.3.5
开发环境:Window 10 + JDK 1.7 + IDEA 2017
环境准备:
集成POM依赖:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>2.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>2.3.5</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.1</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.17</version>
</dependency>
添加Spring配置:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/data/elasticsearch
http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd
">
<!-- 开启配置扫描 -->
<context:component-scan base-package="com.jiangzh"></context:component-scan>
<!-- 随便配置一个ES的节点信息,并且开启嗅探功能,会自动发现集群 -->
<elasticsearch:transport-client id="client"
cluster-name="my-application"
client-transport-sniff="true"
cluster-nodes="192.168.4.109:9300" />
<!-- 配置Spring-data对es提供的template -->
<bean name="elasticsearchTemplate"
class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate">
<constructor-arg name="client" ref="client" />
</bean>
</beans>
创建数据实体,与数据字段一一对应,用来进行快速查询使用:
public class AppPOJO {
private int res_pk;
private String res_kaipk;
private String res_name;
// 省略getter和setter方法
}
创建VO实体,按实际需要,将数据实体转换为业务实体,并返回:
@Document(indexName = "testidex",type = "estype")
public class AppModel {
@Id
private Integer appId; private String resName;
// 省略其他属性以及getter和setter方法
}
开发搜索功能:
1、数据层:
提供了基本的数据支撑,包含了基本的CRUD操作:
新增功能的核心实现:
String pid = et.index(new IndexQueryBuilder()
// 获取数据操作的index
.withIndexName(ESConst.ESIndexEnum.APPSEARCH.getName())
// 获取数据操作的Type
.withType(ESConst.ESTypeEnum.APPSEARCH.getName())
// 设置数据ID,如果不设置会自动生成
.withId("" + pojo.getRes_pk())
// 具体新增的数据
.withSource(jsonData)
.build()
);
2、修改功能核心实现
IndexRequest indexRequest = new IndexRequest();
indexRequest.source(jsonData);
UpdateQuery updateQuery = new UpdateQueryBuilder()
.withIndexName(ESConst.ESTypeEnum.APPSEARCH.getName())
.withType(ESConst.ESTypeEnum.APPSEARCH.getName())
.withId(""+pojo.getRes_pk())
.withIndexRequest(indexRequest)
.withClass(AppPOJO.class)
.build();
et.update(updateQuery);
3、删除功能核心实现
DeleteQuery deleteQuery = new DeleteQuery();
deleteQuery.setQuery(QueryBuilders.termQuery("appId", ""+appUid));
deleteQuery.setIndex(ESConst.ESIndexEnum.APPSEARCH.getName());
deleteQuery.setType(ESConst.ESTypeEnum.APPSEARCH.getName());
et.delete(deleteQuery);
4、根据主键进行查询
StringQuery query = new StringQuery(
QueryBuilders.termQuery("appId",appUid).toString()
);
AppPOJO appPOJO = et.queryForObject(query,AppPOJO.class);
这里一定要注意,使用这个API的时候,要对实体Model进行注解标记,详见代码
5、查询所有数据,用于首页展示,核心代码如下:
// 使用Scan方式进行扫描,可以提高查询速度
// 设置查询条件
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withIndices(ESConst.ESIndexEnum.APPSEARCH.getName())
.withTypes(ESConst.ESTypeEnum.APPSEARCH.getName())
.withQuery(QueryBuilders.matchAllQuery())
.withFilter(QueryBuilders.termQuery("res_online","y"))
.withPageable(new PageRequest(0,1)).build();
// 通过查询条件,生成扫描编号
String scrollId = et.scan(searchQuery, 1000, false);
// 通过扫描编号进行数据匹配
Page page = et.scroll(scrollId, 5000L,AppPOJO.class);
List<AppPOJO> content = null;
if(page.hasContent()){
content = page.getContent();
}else{
break;
}
6、获取查询的总数据,主要用于前台页面分页使用
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withIndices(ESConst.ESIndexEnum.APPSEARCH.getName())
.withTypes(ESConst.ESTypeEnum.APPSEARCH.getName())
.withQuery(QueryBuilders.multiMatchQuery(condition
,"column1","column2"))
.build();
long count = et.count(searchQuery);
以上,所有数据层的基础API已经完成,其余业务代码由于每个人的业务都不相同,我就不一一分享了,大家可以自行脑补。
最后,上述都是核心代码