数据结构
- 结构化:指具有固定格式或有限长度的数据,如数据库,元数据等。
- 非结构化:指不定长或无固定格式的数据,如邮件,word文档等。
非结构化数据的检索
- 顺序扫描法
- 全文搜索
全文搜索
- 概念:全文搜索是一种将文件中所有文本与搜索项匹配的文字资料检索方法。
-
实现原理:
- 实现技术
基于java的开源实现:Lucene,ElasticSerach,Solr
ElasticSearch简介
- 高度可扩展的开源全文搜索和分析引擎
- 快速地、近实时地对大数据进行存储、搜索和分析。
- 用来支撑有复杂的数据搜索需求的企业级应用
ElasticSearch特点
- 分布式
- 高可用
- 多类型
- 多API
- 面向文档
- 异步写入
- 近实时
- 基于Lucene
- 遵循Apache协议
ElasticSearch核心概念
- 近实时
- 集群
- 节点
- 索引
- 类型
- 文档
- 分片
- 副本
elastic search参考资料
http://www.ruanyifeng.com/blog/2017/08/elasticsearch.html
示例
首先我们配置一下环境,在pom.xml文件中添加依赖:
org.springframework.boot
spring-boot-starter-data-elasticsearch
net.java.dev.jna
jna
3.0.9
上述依赖中发现,此处使用的是spring data+elasticsearch模块,在使用时遵循了jpa那套东西,还有一个jna依赖,这个是es需要的依赖,加上就行。
接下来我们先从实现一个es实体类开始:
package com.yun.hello.domain;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlRootElement;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
@Document(indexName = "blog", type = "blog", shards = 1, replicas = 0, refreshInterval = "-1")
@XmlRootElement // MediaType 转为 XML
public class Blog implements Serializable {
private static final long serialVersionUID = 1L;
@Id // 主键
private String id; // 用户的唯一标识
private String title;
private String content;
protected Blog() { // JPA 的规范要求无参构造函数;设为 protected 防止直接使用
}
public Blog(String name, String content) {
this.title = name;
this.content = content;
}
public Blog(String id, String name, String content) {
this.id = id;
this.title = name;
this.content = content;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
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;
}
@Override
public String toString() {
return String.format(
"User[id=%d, title='%s', content='%s']",
id, title, content);
}
}
注解@Document表明这是一个es实体类,为帮助理解,索引index类似于数据库的数据库名,类型type类似于数据库表名,其他的配置此处先不阐述,我们先大致实现功能再说。
接下来我们实现es的资源库:
package com.yun.hello.repository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import com.yun.hello.domain.Blog;
public interface BlogRepository extends ElasticsearchRepository {
/**
* 根据用户名分页查询用户列表
* @param name
* @param pageable
* @return
*/
Page findByTitleLikeOrContentLike(String title, String content, Pageable pageable);
}
它继承了ElasticsearchRepository接口,在使用时通过方法名称的描述来替代类似于sql语句的效果。上述定义的方法即是实现通过标题title或者内容content进行模糊查找。
这样我们就实现了基本的es查找,最后我们测试一下效果:
package com.yun.hello.repository;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.test.context.junit4.SpringRunner;
import com.yun.hello.domain.Blog;
@RunWith(SpringRunner.class)
@SpringBootTest
public class BlogRepositoryTest {
@Autowired
private BlogRepository blogRepository;
@Test
public void testFindByTitleLikeOrContentLike() {
// 清空所有
blogRepository.deleteAll();
blogRepository.save(new Blog("1","老卫跟你谈谈安装 Elasticsearch",
"关于如何来安装 Elasticsearch,这个请看我的博客 https://waylau.com"));
blogRepository.save(new Blog("2","老卫跟你谈谈 Elasticsearch 的几个用法",
"关于如何来用 Elasticsearch,还是得看我的博客 https://waylau.com,酒")); // 关键字"妹"
blogRepository.save(new Blog("3","老卫和你一起学 Elasticsearch",
"如何来学习 Elasticsearch,最终看我的博客 https://waylau.com,酒")); // 关键字"酒"
blogRepository.save(new Blog("4","03-05 用大白话聊聊分布式系统",
"一提起“分布式系统”,大家的第一感觉就是好高大上啊,深不可测"));
blogRepository.save(new Blog("5","02-19 Thymeleaf 3 引入了新的解析系统",
"如果你的代码使用了 HTML5 的标准,而Thymeleaf 版本来停留在 2.x ,那么如果没有把闭合"));
blogRepository.save(new Blog("6","02-19 使用 GFM Eclipse 插件时,不在项目里面生成 HTML 文件",
"GFM 是 GitHub Flavored Markdown Viewer 的简称,是一款对 GitHub 友好的 Markdown 编辑器 。"));
Pageable pageable = new PageRequest(0, 20);
Page page = blogRepository.findByTitleLikeOrContentLike("妹", "酒", pageable);
assertThat(page.getTotalElements()).isEqualTo(2);
}
}
在上述例子中,自动注入了我们刚才实现的blogRepository资源库。通过调用save方法就可以实现es的保存功能。最后blogRepository.findByTitleLikeOrContentLike
这句实现了标题或者内容的模糊查询,符合条件的只有ID为2和3的数据,所以断言是true。这样我们的功能就大体实现了。
elastic search中文文档地址:
http://blog.didispace.com/books/elasticsearch-definitive-guide-cn/
下面是针对上面中文文档的相关学习笔记:
1.首先首先去elasticsearch官网上去下载es:
https://www.elastic.co/downloads/past-releases
下载后进入/bin目录下就可以直接启动es了:
./elasticsearch
启动后执行curl 'http://localhost:9200/?pretty'
收到返回如下:
{
"name" : "wpB9QYp",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "PQIrgUzpRU-7r_Ygy4JZDw",
"version" : {
"number" : "6.1.4",
"build_hash" : "d838f2d",
"build_date" : "2018-03-14T08:28:22.470Z",
"build_snapshot" : false,
"lucene_version" : "7.1.0",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
说明启动成功。