Smartcxr 2017-12-28
背景描述:
系统搜索推广活动,由以前的数据库模糊匹配的方式切换为搜索引擎的方式,选用的内容以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已经完成,其余业务代码由于每个人的业务都不相同,我就不一一分享了,大家可以自行脑补。
最后,上述都是核心代码,我会把工程测试代码发到附件中给大家分享
另外一部分,则需要先做聚类、分类处理,将聚合出的分类结果存入ES集群的聚类索引中。数据处理层的聚合结果存入ES中的指定索引,同时将每个聚合主题相关的数据存入每个document下面的某个field下。