Loading...

zinsearch实现网站内容搜索

日常推荐4个月前更新 Jone
163 0 0

作为elasticsearch的平替——zincsearch,其最大的优点就是轻量。由Go语言实现的它天生就有着占用资源少,启动快等优势。对于一些小站来说,如果不想使用数据库的模糊查询作为网站的搜索方式,那么zincsearch未尝不是一种更好的选择。

接下来介绍下zinsearch的安装与使用。

安装

官网:安装 – 《ZincSearch 中文文档 – 帮助手册 – 教程》 – 极客文档 (geekdaxue.co)

zincsearch官网有安装教程,推荐使用Docker进行安装,可以省下许多配置环境的时间。

官网没有使用docker-compose的安装教程,在此发下我的docker-compose.yml文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
version: '3.5'

services:
zinc: ## mqtt 服务
image: public.ecr.aws/zinclabs/zinc:latest
environment:
- ZINC_FIRST_ADMIN_USER=admin
- ZINC_FIRST_ADMIN_PASSWORD=admin
ports:
- "4080:4080"
volumes:
- ./data:/data
restart: always

默认拉取最新的zinc镜像,默认账号密码都是admin。

使用

zincsearch兼容elasticsearch部分api,如果你之前使用过它那么你将会很快上手zincsearch。

首先需要创建个index。index相当于mysql的数据库。建议调用api创建index,直接写死在代码里,要不然每次还得手动创建。

因为刚开始使用,了解也不太多,就简单介绍下网站使用到的插入查找功能。

插入

zinsearch自带swagger页面,可以去查找相关功能的实现接口。

例如插入功能就可以使用**/api/{index}/_doc/{id}**这个接口。指定id可以在更新document时知道操作的是哪一个,那么想插入一个id等于1的document就可以如下操作。

下面给个使用java封装调用插入document的示例。

1
2
3
4
5
6
7
8
9
10
11
public void insertData(ZincInsertDto zincInsertDto){
String uri = zincProperties.getIp()+"/api/"+zincProperties.getIndex()+"/_doc/"+zincInsertDto.getId();
String auth = "Basic "+ Base64Util.base64Encode(zincProperties.getUsername()+":"+zincProperties.getPassword());
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Authorization",auth);
Map<String,String> map = new HashMap<>();
map.put("title",zincInsertDto.getTitle());
map.put("content",zincInsertDto.getContent());
HttpEntity<Object> httpEntity = new HttpEntity<Object>(map,httpHeaders);
restTemplate.put(uri,httpEntity);
}

上面示例中index有两个额外的属性titlecontent,都是通过dto传过来的。同时请求的时候需要加上身份验证,即httpHeaders内容。

查询

zinsearch查询功能建议使用**/es/{index}/_search**接口。

因为查询时可以配置条件过多,这里就不一一介绍了,简单介绍下几个常用的参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"from": 0,
"size": 20,
"query":{
"multi_match":{
"query":"测试",
"fields":["title","content"]
}
},
"highlight": {
"fields": {
"title":{},
"content":{}
}
}
}

from:从哪条开始查询。

size:最多返回多少个查询结果。

query:查询条件,其中multi_match表示可以从多个属性里查询;示例中的index里有title和content两个属性值,即这个查询条件是查询标题和内容里所有含有测试的document。

highlight:表示返回的document,其中匹配到的词语会被高亮。

下图是一个java封装的查询请求示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public ResponseDto getSearchResult(@RequestBody String condition){
String query = "{\n" +
" \"from\": 0,\n" +
" \"size\": 20,\n" +
" \"query\":{\n" +
" \"multi_match\":{\n" +
" \"query\":\""+condition+"\",\n" +
" \"fields\":[\"title\",\"content\"]\n" +
" }\n" +
" },\n" +
" \"highlight\": {\n" +
" \"fields\": {\n" +
" \"title\":{},\n" +
" \"content\":{}\n" +
" }\n" +
" }\n" +
"}";
Map map = JSON.parseObject(query,new TypeReference<Map>(){});
return ResponseDto.Ok(zincUtil.getSearchResult(map));
}
public Object getSearchResult(Map query){
String uri = zincProperties.getIp()+"/es/"+zincProperties.getIndex()+"/_search";
String auth = "Basic "+ Base64Util.base64Encode(zincProperties.getUsername()+":"+zincProperties.getPassword());
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Authorization",auth);
HttpEntity<Object> httpEntity = new HttpEntity<Object>(query,httpHeaders);
Object responseDto = restTemplate.postForObject(uri,httpEntity, Object.class);
return responseDto;
}

同样,调接口时需要身份认证,封装好传给httpEntity即可。

© 版权声明

相关文章