Elasticsearch:一个集群性质的Lucene搜索引擎
因为项目需要实现按关键字匹配排序功能,本来想用Lucence的,但是L本身只是一个基础library,实际应用的话目测代码量比较大,小公司实现比较吃力,所以使用了elasticsearch,可以集群便于扩展。初次使用,介绍一下简单的入门,不涉及任何高端技巧,熟悉的朋友不用看了,浪费时间。
项目一直使用的spring-boot-starter
,顺便找了一下,果然找到有社区贡献的集成jar
,很厚脸皮的直接拿过来用了,项目地址:https://github.com/spring-projects/spring-data-elasticsearch,注意:这里的client版本支持的是1.5.2
,官方最新版本已经到2.1
了,社区版本目前支持较低,反正我是初学,先学会使用。
开始动手:
添加依赖
<!-- maven -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>1.3.0.RELEASE</version>
</dependency>
# gradle
dependencies {
compile "org.springframework.boot:spring-boot-starter-data-elasticsearch"
}
-
配置
<!-- xml --> <?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" xsi:schemaLocation="http://www.springframework.org/schema/data/elasticsearch http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <elasticsearch:node-client id="client" local="true"/> <bean name="elasticsearchTemplate" class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate"> <constructor-arg name="client" ref="client"/> </bean> </beans>
注意
local="true"
,表示client
启动在本地,经试验,没有什么实际用途,内存占用严重,里面在集成店别的东西,很容易内存溢出,仅作演示用。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" xsi:schemaLocation="http://www.springframework.org/schema/data/elasticsearch http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <elasticsearch:repositories base-package="com.xyz.acme"/> <elasticsearch:transport-client id="client" cluster-nodes="ip:9300,ip:9300" cluster-name="elasticsearch" /> <bean name="elasticsearchTemplate" class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate"> <constructor-arg name="client" ref="client"/> </bean> </beans>
#java config:
#application.properties:
esearch.host=192.168.199.150
esearch.port=9300
@Configuration
@EnableElasticsearchRepositories(basePackages = "org/aybx/wishes/user/elastic")
public class ElasticSearchConfig {
@Value("${esearch.port}") int port;
@Value("${esearch.host}") String hostname;
@Bean
public ElasticsearchOperations elasticsearchTemplate() {
return new ElasticsearchTemplate(client());
}
@Bean
public Client client(){
TransportClient client= new TransportClient();
TransportAddress address = new InetSocketTransportAddress(hostname, port);
client.addTransportAddress(address);
return client;
}
}
basePackages
包含继承spring-data
的Repositories
我的包结构如下:
ESUser
类需要注解@Document(indexName = "user")
,指定id
,ES的目录结构大概是/index/type/documentId
,ESUserRepository
需要继承ElasticsearchCrudRepository
,Service是正常的业务代码,测试代码:
@RunWith(value = SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = BootStartup.class)
@WebAppConfiguration
@ActiveProfiles("scratch")
public class ESUserServiceTest {
private static final Logger LOGGER = LoggerFactory.getLogger(ESUserServiceTest.class);
@Autowired
IESUserService iesUserService;
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
@Test
public void testSave() throws Exception {
ESUser user = new ESUser();
user.setId(1L);
user.setContent("接机,包房,做饭");
user = iesUserService.save(user);
LOGGER.info("user, {}", JSON.toJSONString(user));
ESUser user1 = new ESUser();
user1.setId(2L);
user1.setContent("接机,包房");
user1 = iesUserService.save(user1);
LOGGER.info("user1, {}", JSON.toJSONString(user1));
ESUser user2 = new ESUser();
user2.setId(3L);
user2.setContent("包房,做饭");
user2 = iesUserService.save(user2);
LOGGER.info("user2, {}", JSON.toJSONString(user2));
}
@Test
public void testFind() throws Exception {
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(queryStringQuery("接机 OR 做饭")).withFields("content").build();
List<ESUser> esUsers = elasticsearchTemplate.queryForList(searchQuery, ESUser.class);
for (ESUser user : esUsers) {
LOGGER.info("user:{}, content:{}", user.getId(), user.getContent());
}
}
}
这里没有用service调用,写了一个简单的查询,接机
和做饭
中间的OR
表示匹配或的意思,还有很多可以操作的地方,详细可以参考官方文档,比如增加一个条件的权重,筛选多余的filed
,筛选子类的属性等等;感觉复杂到不行,不过也对,搜索的时候必然会有这样的需要,也很符合实际情况。
最后说一下ES的插件用法,比如常见的monitor功能:Marvel,安装,/bin/plugin install elasticsearch/marvel/latest
,这是低版本的装法,新版参考文档