ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。
ES是ElasticSearch的缩写;
ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是开源软件。
一般公司都是用ELK做日志分析,社区搜索之类的,很少单独使用ElasticSearch。但是单独使用ElasticSearch也很广泛,没有ELK的时候都是这样玩的。
比如我的社区网站(https://www.pomit.cn)就用了ElasticSearch做社区搜索,一开始做搜索的时候,曾有三种方案:
**如果大家正在寻找一个java的学习环境,或者在开发中遇到困难,可以<a
href="https://jq.qq.com/?_wv=1027&k=52sgH1J"
target="_blank">
加入我们的java学习圈,点击即可加入
</a>
,共同学习,节约学习时间,减少很多在学习中遇到的难题。**
本文假设你已经引入Spring必备的一切了,已经是个Spring项目了,如果不会搭建,可以打开这篇文章看一看《Spring和Spring Mvc 5整合详解》。
使用elasticsearch需要引入spring-data-elasticsearch,而且要保证版本和安装的elasticsearch对应。
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.pomit</groupId>
<artifactId>SpringWork</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>Elasticsearch</artifactId>
<packaging>jar</packaging>
<name>Elasticsearch</name>
<url>http://maven.apache.org</url>
<properties>
<!-- redis 版本 -->
<elasticsearch.version>3.1.6.RELEASE</elasticsearch.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
</dependencies>
<build>
<finalName>Elasticsearch</finalName>
</build>
</project>
父模块可以在https://www.pomit.cn/spring/SpringWork/pom.xml获取。
需要配置elasticsearchTemplate和elasticsearch:transport-client。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/elasticsearch http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="annotationPropertyConfigurerElasticsearch"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="order" value="1" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="locations">
<list>
<value>classpath:elasticsearch.properties</value>
</list>
</property>
</bean>
<elasticsearch:transport-client id="client"
cluster-nodes="${elasticsearch.cluster-nodes}" cluster-name="${elasticsearch.cluster-name}" />
<bean name="elasticsearchTemplate"
class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate">
<constructor-arg ref="client" />
</bean>
<elasticsearch:repositories base-package="cn.pomit.springwork.elasticsearch.dao" />
</beans>
elasticsearch.properties中存放elasticsearch的地址端口信息。
elasticsearch.properties:
elasticsearch.cluster-name=elasticsearch
elasticsearch.cluster-nodes=127.0.0.1:9300
我们直接使用Spring-data-elasticsearch, 一切都会变的特别简单。Spring-data-elasticsearch支持快速查询,也支持@Query之定义查询,要注意它的写法,和elasticsearch原生写法略有不同。
QuestionElasticsearchRepository :
package cn.pomit.springwork.elasticsearch.dao;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.annotations.Query;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import cn.pomit.springwork.elasticsearch.domain.FQuestionElasticssearch;
public interface QuestionElasticsearchRepository extends ElasticsearchRepository<FQuestionElasticssearch, Long> {
Page<FQuestionElasticssearch> findByCatory(String catory, Pageable pageable);
@Query("{ \"bool\":{ \"must\":[ { \"multi_match\": { \"query\": \"?0\", \"type\": \"most_fields\", \"fields\": [ \"title\", \"content\" ] } }, { \"match\": { \"catory\": \"?1\" } } ] } } ")
Page<FQuestionElasticssearch> searchByKeyWordsAndCatory(String keyword, String catory, Pageable pageable);
}
这个写法和Spring-data-jpa基本上一样,应该说Spring-data系列的写法都是类同的。
注意,FQuestionElasticssearch实体需要加上@Document注解指明Elasticssearch中的index和type。
我们定义一个service和web接口来做测试。
QuestionElasticsearchService:
package cn.pomit.springwork.elasticsearch.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import cn.pomit.springwork.elasticsearch.dao.QuestionElasticsearchRepository;
import cn.pomit.springwork.elasticsearch.domain.FQuestionElasticssearch;
@Service
public class QuestionElasticsearchService {
@Autowired
QuestionElasticsearchRepository questionElasticsearchRepository;
public Page<FQuestionElasticssearch> pageByOpenAndCatory(Integer page, Integer size, String catory,
String keyWord) {
Pageable pageable = PageRequest.of(page, size);
if (StringUtils.isEmpty(keyWord)) {
return questionElasticsearchRepository.findByCatory(catory, pageable);
} else {
return questionElasticsearchRepository.searchByKeyWordsAndCatory(keyWord, catory, pageable);
}
}
}
ElasticsearchRest:
package cn.pomit.springwork.elasticsearch.web;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import cn.pomit.springwork.elasticsearch.domain.FQuestionElasticssearch;
import cn.pomit.springwork.elasticsearch.service.QuestionElasticsearchService;
@RestController
@RequestMapping("/elsearch")
public class ElasticsearchRest {
@Autowired
QuestionElasticsearchService questionElasticsearchService;
@RequestMapping(value = "/test", method = { RequestMethod.GET })
public List<FQuestionElasticssearch> test(@RequestParam(value = "value", required = false) String value) {
return questionElasticsearchService.pageByOpenAndCatory(0, 10, "Spring专题", value).getContent();
}
}
FQuestionElasticssearch:
package cn.pomit.springwork.elasticsearch.domain;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
@Document(indexName = "pomit", type = "issue", createIndex = false)
public class FQuestionElasticssearch {
@Id
private Long id;
private String title;
private String catory;
private String content;
public FQuestionElasticssearch() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public void setCatory(String catory) {
this.catory = catory;
}
public String getCatory() {
return catory;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}