1.存储结构
Elasticsearch是文件存储,Elasticsearch是面向文档型数据库,一条数据在这里就是一个文档,用JSON作为文档序列化的格式,比如这样:
{
"name" : "xiaoming",
"age" : 0
}
关系型数据库:
数据库(会员数据库) ——> 表(用户表) ——>行 ——> 列(Columns)
Elasticsearch:
索引(Index) ——> 类型(type) ——>文档 (Documents)——> 字段(Fields)
2.安装Elasticsearch及kibana
需要jdk环境,并且运行会占用1G内存
不允许root用户启动es,默认外部不能访问,访问地址为 IP:9200
其余问题自行百度
kibana版本要与es一致
修改config下文件,解放server.port,修改server.host为本机IP,解放并修改elasticsearch.hosts为es地址
访问地址为 IP:5601
3.es基础语法
在kibana主页切换到dev tools
# 删除索引
DELETE /mymayikt
# 新建索引
PUT /mymayikt
# 获取索引
GET /mymayikt
# 建立文档 /索引/类型/id
PUT /mymayikt/user/9
{
"name":"mooyt",
"age":20,
"sex":0
}
GET /mymayikt/user/4
# 不传入id的情况
POST /mymayikt/user/
{
"name":"ma",
"age":215,
"sex":0
}
GET /mymayikt/user/6-18PWkB8UeMF1fSscek
# 查询所有
GET /mymayikt/user/_search
# 查询指定id
GET /mymayikt/user/_mget
{
"ids":[1,4]
}
# 条件查询
GET /mymayikt/user/_search?q=age:1
# 条件查询
GET /mymayikt/user/_search?q=age:[10 TO 60]&sort=age:desc
# 分页,从第0到第二条数据
GET /mymayikt/user/_search?from=0&size=2
# term为精确查询
# 模糊查询 支持分词
GET mymayikt/user/_search
{
"from": 0,
"size": 2,
"query": {
"match": {
"name":"mooyt"
}
}
}
4.springboot整合es
4.1简单案例
创建springboot项目,创建实体类UserEntity
@Document(indexName="mymayikt",type="user")
@Data
public class UserEntity {
@Id
private String id;
private String name;
private Integer age;
private Integer sex;
}
创建UserDao类,这里直接继承JPA
@Repository
public interface UserDao extends CrudRepository<UserEntity,String> {
}
创建UserController类
@RestController
public class UserController {
@Autowired
private UserDao userDao;
@RequestMapping("/addUser")
public UserEntity addUser(@RequestBody UserEntity userEntity) {
return userDao.save(userEntity);
}
//查询文档
@RequestMapping("/findById")
public Optional<UserEntity> findById(String id) {
return userDao.findById(id);
}
}
前台页面index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/addUser" datatype="">
d
<input name="id">
<input name="name">
<input name="sex">
<input name="age">
<input type="submit" value="dian">
</form>
</body>
</html>
application.properties配置文件
spring.data.elasticsearch.cluster-name=yourname
spring.data.elasticsearch.cluster-nodes=yourIP:9300
spring.http.encoding.charset=UTF-8
server.port=8080
利用Postman测试
http://localhost:8080/addUser 写入json
{
"id":2,
"name":"lis2",
"sex":0,
"age":2
}
在kibana中查询
GET mymayikt/user/2
得到以下结果:
{
"_index" : "mymayikt",
"_type" : "user",
"_id" : "2",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 3,
"found" : true,
"_source" : {
"id" : "2",
"name" : "lis2",
"age" : 2,
"sex" : 0
}
}
利用Postman查询
http://localhost:8080/findById?id=2 得到
{
"id": "2",
"name": "lis2",
"age": 2,
"sex": 0
}
查询成功!
4.2 手动模拟数据案例
创建实体类EsBlog
@Document(indexName = "blog" ,type = "blog")
@Data
public class EsBlog implements Serializable {
@Id
private String id;
private String title;
private String summary;
private String content;
}
创建数据操作类EsBlogRepository
@Repository
public interface EsBlogRepository extends ElasticsearchRepository<EsBlog,String> {
Page<EsBlog> findByTitleLikeOrContentLike(String title, String summary,String content, Pageable pageable);
}
编写测试用例
@RunWith(SpringRunner.class)
@SpringBootTest
public class Elasticsearch02ApplicationTests {
@Autowired
private EsBlogRepository es;
@Before
public void initRepository() {
es.deleteAll();
es.save(new EsBlog("额诶诶", "跌名", "eee,xxxtg,bmfls,hzbqqb"));
es.save(new EsBlog("额诶", "名", "g,bmfls,hzbqqb"));
es.save(new EsBlog("额", "跌", "eee,,bmfls,hzbqqb"));
es.save(new EsBlog("诶", "跌名", "eee,xxxtg,bmfls,hzbqqb"));
es.save(new EsBlog("诶诶", "跌名", "hzbqqb"));
es.save(new EsBlog("额s", "跌", "e产品特别图片图片"));
es.save(new EsBlog("算法", "java", "eee这是应该的"));
}
@Test
public void findByTitleLikeOrContentLike() {
Pageable pageable = PageRequest.of(0, 20);
String title = "额";
String summary = "跌";
String content = "eee";
Page<EsBlog> page = es.findByTitleLikeOrContentLike(title, summary, content, pageable);
System.out.println("----------------");
for (EsBlog blog : page.getContent()) {
System.out.println(blog.toString());
}
}
}
查询结果类似这样
EsBlog{id='NFWR5mkB3Hevp7XrnNWm', title='额s', summary='跌', content='e产品特别图片图片'}
EsBlog{id='MFWR5mkB3Hevp7XrnNVM', title='额诶', summary='名', content='g,bmfls,hzbqqb'}
EsBlog{id='L1WR5mkB3Hevp7XrnNUc', title='额诶诶', summary='跌名', content='eee,xxxtg,bmfls,hzbqqb'}
EsBlog{id='MVWR5mkB3Hevp7XrnNVh', title='额', summary='跌', content='eee,,bmfls,hzbqqb'}
定义BlogController类
@RestController
@RequestMapping("/blogs")
public class BlogController {
@Autowired
private EsBlogRepository es;
@RequestMapping("/list")
public List<EsBlog> list(@RequestParam(value = "title")String title ,
@RequestParam(value = "summary")String summary ,
@RequestParam(value = "content")String content ,
@RequestParam(value = "pageIndex",defaultValue = "0")int pageIndex ,
@RequestParam(value = "pageSize",defaultValue = "10")int pageSize){
//数据在test初始化
Pageable pageable = PageRequest.of(pageIndex, pageSize);
Page<EsBlog> page = es.findByTitleLikeOrContentLike(title, summary,content, pageable);
return page.getContent();
}
}
启动并访问
http://localhost:8080/blogs/list?title=%E9%A2%9D&summary=eee&content=eee
返回结果类似这样
[
{
"id": "L1WR5mkB3Hevp7XrnNUc",
"title": "额诶诶",
"summary": "跌名",
"content": "eee,xxxtg,bmfls,hzbqqb"
},
{
"id": "MVWR5mkB3Hevp7XrnNVh",
"title": "额",
"summary": "跌",
"content": "eee,,bmfls,hzbqqb"
},
{
"id": "NFWR5mkB3Hevp7XrnNWm",
"title": "额s",
"summary": "跌",
"content": "e产品特别图片图片"
},
]
5.9200与9300端口号区别
9200端口号暴露es restful接口
利用es提供的restful接口查询
http://ip:9200/mymayikt/user/2
{"_index":"mymayikt","_type":"user","_id":"2","_version":1,"_seq_no":0,"_primary_term":3,"found":true,"_source":{"id":"2","name":"lis2","age":2,"sex":0}}
9300是TCP协议端口号,es集群之间通讯端口号
6.中文分词器
6.1分词器设置
下载与版本对应的分词器
解压到es/plugins下命名为ik,重启即可
利用Postman发送到 http://ip:9200/_analyze
{
"analyzer":"ik_smart",
"text":"绝地求生"
}
返回数据为
{
"tokens": [
{
"token": "绝地求生",
"start_offset": 0,
"end_offset": 4,
"type": "CN_WORD",
"position": 0
}
]
}
6.2.分词器的扩展
停掉es
到es/plugins/ik/config目录下
mkdir dic
cd dic
vim new_word.dic
何以解忧
cd ..
vim IKAnalyzer.cfg.xml
<entry key="ext_dict">dic/new_word.dic</entry>
启动服务
利用Postman发送到 http://ip:9200/_analyze
{
"analyzer":"ik_smart",
"text":"何以解忧"
}
返回数据为
{
"tokens": [
{
"token": "何以解忧",
"start_offset": 0,
"end_offset": 4,
"type": "CN_WORD",
"position": 0
}
]
}
7.指定文档映射类型
指定age为integer类型,name为text类型
DELETE /mymayikt
PUT /mymayikt
# 指定类型
POST /mymayikt/_mapping/user
{
"user" : {
"properties" : {
"age" : {
"type" : "integer"
},
"name" : {
"type" : "text"
"analyzer" : "ik_smart"
}
}
}
}
PUT mymayikt/user/1
{
"name":"好好学习",
"age":"1"
}
PUT mymayikt/user/2
{
"name":"华为p10",
"age":"1"
}
PUT mymayikt/user/3
{
"name":"撒播",
"age":"1"
}
# 查询
GET mymayikt/user/_search
{
"from": 0,
"size": 2,
"query": {
"match": {
"name":"华为"
}
}
}
"type" : "keyword"将不做分词查询