上一篇:https://blog.csdn.net/fengxianaa/article/details/125150994
1. 使用
1. 操作索引
1. 使用postman
- 添加索引,必须使用 put 请求,比如:192.168.56.107:9200/goods_indes
- 查询索引,使用 get 请求,只需要把 put 改成 get 就行
如果有想查询多个索引,逗号分隔,比如:192.168.56.107:9200/goods_index,goods_index2
_all:查询所有索引
- 删除索引,使用 delete 请求
- 关闭索引,表示不想删除也不想让外界访问,post 请求
使用 _close ,比如:
- 打开索引,也是 post 请求,使用_open
2. 使用Kibana
# 查询所有索引,会返回很多默认索引 GET _all # 创建索引 PUT person # 查询索引 GET person # 关闭索引 POST person/_close # 打开索引 POST person/_open # 删除索引 DELETE person
2. 操作映射--Mapping
之前说过 mapping 中定义字段的类型,所以先了解一下ES中的数据类型
1. 数据类型
- 字符串
- text:对内容进行分词,得出多个词条
- 比如:“华为手机”分词后,得到两个词条:华为、手机
- 一般存储:网页内容、文章、日志等
- 比如:“华为手机”分词后,得到两个词条:华为、手机
- keyword:不会对内容进行分词,将内容当作一个词条
- 一般存储:电话、邮编、邮箱等
- text:对内容进行分词,得出多个词条
- 数值
-
- scaled_float 缩放类型的的浮点数
- ⽐如价格只需要精确到分,缩放因⼦为100,price=57.34,存起来就是5734
-
- 布尔,boolean
- 日期类型,date
- 数组:[],被一对儿中括号扩起来
- 对象:{},被一对儿大括号扩起来
2. 操作映射
相当于定义一个表的结构,我们使用Kibana操作
- 创建映射
# 1. 创建索引 PUT hero # 2. 创建mapping, 定义两个字段 PUT hero/_mapping { "properties":{ "name":{ "type":"keyword" }, "skill":{ "type":"text" } } }
查询索引可以看到,添加的 mapping
也可以直接查询 mapping
GET hero/_mapping
也可以在创建索引的同时,添加映射
先删除 hero这个索引,然后执行:
# 创建索引,并添加映射
PUT hero
{
"mappings": {
"properties": {
"name":{
"type":"keyword"
},
"skill":{
"type":"text"
}
}
}
}
- 添加字段
# 添加字段
PUT hero/_mapping
{
"properties":{
"skill_num":{
"type":"integer"
}
}
}
3. 操作文档
- 添加文档
# 添加文档
POST hero/_doc
{
"name":"亚瑟",
"skill":"从天而降大宝剑",
"skill_num":3
}
也可以添加时,指定id
# 添加文档
POST hero/_doc/1
{
"name":"吕布",
"skill":"心中的黑暗,在无限膨胀",
"skill_num":3
}
- 查询文档
# 查询单个文档 GET hero/_doc/1
# 查询一个不存在的文档 GET hero/_doc/2
查询所有文档
# 查询所有文档 GET hero/_search
- 修改文档
# 修改文档,当id存在时:修改,不存在时:新增
POST hero/_doc/1
{
"name":"吕布",
"skill":"心中的黑暗,在无限膨胀,哈哈",
"skill_num":3
}
注意:就算只更新一个字段也需要传整个对象,否则不传的字段会当成空处理
# 修改文档,不传 skill_num,再次查询,skill_num 就没有了
POST hero/_doc/1
{
"name":"吕布",
"skill":"心中的黑暗,在无限膨胀,哈哈"
}
当然也可以只修改某个字段
# 只修改指定字段
POST hero/_update/1
{
"doc": {
"skill_num":4
}
}
再次查询:
- 删除文档
# 根据id删除
DELETE hero/_doc/60NWooABIuAyT-o-ys22
删除不存在的数据返回:not_found
# 删除不存在的数据
DELETE hero/_doc/2
4. 分词器
1. 默认分词器
分词器:将一段文字,按照规则,切分成多个词语的工具,比如:华为手机,分词后:华为、手机
ES内置了很多分词器:
- standard : 默认分词器,按词切分,小写处理
- simple: 按照非字母切分(符号被过滤),小写处理,会去除数字
- whitespace: 按照空格切分,不转小写
- stop: 小写处理,停用词过滤(the,a,is)
- keyword: 不分词,直接将输入当作输出
但是这些我们不用,只做了解,因为它们对中文很不友好,比如:
# 默认分词器
POST _analyze
{
"analyzer": "standard",
"text": ["中华任命共和国"]
}
2. IK分词器
ik分词器是java语言开发的一个中文分词器
下载地址:Release v7.8.0 · medcl/elasticsearch-analysis-ik · GitHub
注意:下载的包一定要和 ElasticSearch 的版本一致
下载后,上传到虚拟机的 /home/soft/elasticsearch-7.8.0/plugins/ik 目录(需要先创建好)
然后执行: unzip elasticsearch-analysis-ik-7.8.0.zip
将 config 目录下的文件 复制到 /home/soft/elasticsearch-7.8.0/config/ 目录
执行:cp -R config/* /home/soft/elasticsearch-7.8.0/config/
最后重启 ES 和 Kibana
3. 基础使用
使用IK有两种方式:ik_smart、ik_max_word
# ik_smart,粗粒度划分,结果会少一些
GET _analyze
{
"analyzer": "ik_smart",
"text": ["中华人民共和国"]
}
# ik_max_word,细粒度划分,结果会多一些
GET _analyze
{
"analyzer": "ik_max_word",
"text": ["中华人民共和国"]
}
4. 操作文档
- 删除之前创建的 hero,重新创建,因为之前用的是默认的 standard 分词器
# 创建索引,指定使用IK分词器
PUT hero
{
"mappings": {
"properties": {
"name":{
"type":"keyword"
},
"skill":{
"type":"text",
"analyzer": "ik_max_word"
}
}
}
}
- 添加文档
# 添加3个文档
PUT hero/_doc/1
{
"name":"亚瑟",
"skill":"王者背负,王者审判,王者不可阻挡!"
}
PUT hero/_doc/2
{
"name":"妲己",
"skill":"羁绊是什么东西"
}
PUT hero/_doc/3
{
"name":"吕布",
"skill":"无法得到那就将他彻底毁掉"
}
- 查询文档
查询分为两种:对关键字分词、不对关键字分词
不对关键字分词,使用“term”
# 通过数据的关键字查询文档,不对关键字分词,相当于数据库查询的“=”
GET hero/_search
{
"query": {
"term": {
"name": {
"value": "妲己"
}
}
}
}
但是查询 skill 字段
可以看到是没有结果了,原因有两个:
- 没有对查询的关键字进行分词
- 我们存储的数据中没有“羁绊是什么东西”这个词条
这时候把查询关键字修改为“羁绊”就能看到结果
对关键字分词,使用“match”
# 对关键分词后再查询
GET hero/_search
{
"query": {
"match": {
"skill": "羁绊是什么"
}
}
}
可以看到查出来了,这是因为“羁绊是什么”分词后的结果是:
5. Java API
操作索引
创建一个普通的Maven项目
pom.xml
<!-- elasticsearch API -->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.8.0</version>
</dependency>
<!-- elasticsearch 的客户端 -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.8.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
- 创建索引
public static void main(String[] args) throws IOException {
//1. 创建ES连接客户端
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("192.168.56.109",9200,"http")));
//2. 创建索引请求
CreateIndexRequest request = new CreateIndexRequest("wangzhe");//fengxiansheng是索引名
//2.1 mapping
String mapping = "{\n" +
" \"properties\":{\n" +
" \"name\":{\n" +
" \"type\":\"keyword\"\n" +
" },\n" +
" \"skill\":{\n" +
" \"type\":\"text\"\n" +
" }\n" +
" }\n" +
"}";
//设置 mapping 的格式是json
request.mapping(mapping, XContentType.JSON);
//2.2 使用client创建索引
CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
//3. 返回true,表示创建成功
System.out.println(response.isAcknowledged());
//4. 关闭客户端
client.close();
}
运行后,在 Kibana 上查看结果
- 查询索引
private static void getIndex() throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
new HttpHost("192.168.56.109",9200,"http")));
GetIndexRequest request = new GetIndexRequest("wangzhe");//wangzhe 是索引名
GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);
//获取结果
Map<String, MappingMetadata> mappings = response.getMappings();
for(String key : mappings.keySet()){
System.out.println(key + "----" + mappings.get(key).sourceAsMap());
}
client.close();
}
结果
- 删除索引
private static void deleteIndex() throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
new HttpHost("192.168.56.109",9200,"http")));
DeleteIndexRequest request = new DeleteIndexRequest("wangzhe");//wangzhe 是索引名
AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
System.out.println(response.isAcknowledged());
client.close();
}
- 判断索引是否存在
private static void existIndex() throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
new HttpHost("192.168.56.109",9200,"http")));
GetIndexRequest request = new GetIndexRequest("wangzhe");//fengxiansheng 是索引名
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
// true:存在,false:不存在
System.out.println(exists);
client.close();
}
2. 操作文档
创建一个 Hero 类
public class Hero {
private String name;
private String skill;
//get、set 省略
}
- 把对象,存到ES中
private static void createDoc() throws IOException {
Hero hero = new Hero();
hero.setName("张飞");
hero.setSkill("英雄比普通人更不正常");
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
new HttpHost("192.168.56.109",9200,"http")));
//组装添加文档的请求
IndexRequest request = new IndexRequest("hero")//hero 是索引名
.id("4")//指定id
.source(JSONObject.toJSONString(hero), XContentType.JSON);//数据内容json格式
//执行添加文档的命令
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
//返回结果
System.out.println(response);
client.close();
}
结果:
Kibana 上查询:
- 修改文档
修改文档跟添加文档的代码一样,id存在就更新,id不存在就添加
private static void updateDOc() throws IOException {
Hero hero = new Hero();
hero.setName("张飞");
hero.setSkill("英雄比普通人更不正常66666");
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
new HttpHost("192.168.56.109",9200,"http")));
//组装添加文档的请求
IndexRequest request = new IndexRequest("hero")//hero 是索引名
.id("4")//指定id
.source(JSONObject.toJSONString(hero), XContentType.JSON);//数据内容json格式
//执行添加文档的命令
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
// 使用UpdateRequest,更新指定字段
// Map<String,Object> map = new HashMap<String, Object>();
// map.put("skill","英雄比普通人更不正常哈哈哈哈");
// UpdateRequest updateRequest = new UpdateRequest("hero","4");
// updateRequest.doc(map);
// UpdateResponse response = client.update(updateRequest, RequestOptions.DEFAULT);
//返回结果
System.out.println(response);
client.close();
}
Kibana 上查询:
- 根据ID查询
private static void getById() throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
new HttpHost("192.168.56.109",9200,"http")));
//创建请求对象,两个参数,分别是:索引名、文档ID
GetRequest request = new GetRequest("hero","1");
GetResponse response = client.get(request, RequestOptions.DEFAULT);
System.out.println(response);
System.out.println(response.getSourceAsMap());
client.close();
}
结果:
- 删除文档
private static void deleteDoc() throws IOException {
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
new HttpHost("192.168.56.107",9200,"http")));
//创建请求对象,两个参数,分别是:索引名、文档ID
DeleteRequest request = new DeleteRequest("person","5");
DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
System.out.println(response);
client.close();
}
结果: