前言
常见的数据类型一般为3种:结构化数据、非结构化数据、半结构化数据。
- 结构化数据,通常会放在关系型数据库,如Mysql,Oracle等
- 非结构化数据,如文档、音频、视频等,是二维结构保存和体现不了数据格式,一般放在MongoDb,Redis等非关系型数据库(K,V结构)
- 半结构化数据,如HTML,XML等数据和格式混在一起的,一般也是放在MongoDb,Redis等非关系型数据库
目前有一个需求:不管你是啥数据类型,都能按我搜索的关键字进行快速查找。
这个需求的难点在于:我们并不能保证所有的数据的类型都是统一的。如果是结构化数据,快速查找可以建索引。非结构可以通过K快速查,而半结构不行,因为K找到V后,V还是数据格式和内容混在一起的
而Elasticsearch解决为了解决上述问题,出现的一种文档型数据库,可保存结构化数据,非结构化数据,半结构化数据,并进行快速查找。
什么是Elasticsearch
The Elastic Stack,包括 Elasticsearch、Kibana、Beats和 Logstash(也称为ELK Stack)。能够安全可靠地获取任何来源、任何格式的数据,然后实时地对数据进行搜索、分析和可视化。
Elaticsearch,简称为ES,ES是一个开源的高扩展的分布式全文搜索引擎,是整个ElasticStack 技术栈的核心。它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。
说简单点:Elasticsearch是Elastic Stack全家桶的一员。
Elasticsearch入门常识
- 9300端口为Elasticsearch集群间组件的通信端口,9200端口为浏览器访问的http协议RESTful端口。
- ES通过Java开发,因此得有JDK支持,最好使用服务器上已有的,不用他内置的。
- 支持和推荐使用HTTP协议,以RESTFUL风格的方式操作数据。
- 数据的请求和响应,ES推荐是JSON格式进行交互
- Java中,如果说万物皆对象。那么Elasticsearch,万物皆索引。他使用的是倒排索引:
- 正排索引。举个例子:
id | content |
---|---|
1001 | zhangsan is my name |
1002 | lisi is my name |
我在ID建立主键索引,根据ID=1001,找到这条数据。这根据编号,找到内容,这类索引叫正排索引
2. 倒排索引。举个例子:
keyword | id |
---|---|
name | 1001,1002 |
lisi | 1002 |
我对内容里的字符串进行索引,根据内容,找到编号,这类索引叫倒排索引。
倒排索引的目的是为了找到编号,进而再根据正排索引找到完全数据来源。
- ES认为GET,PUT,DELETE是幂等性的,而POST为非幂等性,因此成功发送POST请求后,会返回此次操作数据的的唯一标识_id
Elasticsearch名词
Elasticsearch是面向文档型数据库,一条数据在这里就是一个文档。为了方便大家理解,我们将Elasticsearch里存储文档数据和关系型数据库 MySQL存储数据的概念进行一个类比
ES里的Index可以看做一个库,而Types相当于表,Documents则相当于表的行。
这里Types 的概念已经被逐渐弱化,Elasticsearch 6.X中,一个index下已经只能包含一个type,Elasticsearch 7.X中, Type的概念已经被删除了。
总结:type可不用关注,关注index,document,field即可。
HTTP之RESTFUL操作数据
创建、新增,删除索引
之前说过ES是支持且只允许RESTFUL风格操作数据,比如说对索引操作。
查询索引:GET,http://localhost:9200/{索引名}
创建索引:PUT,http://localhost:9200/{索引名}
删除索引:DELETE,http://localhost:9200/
注意:对索引不能使用POST,即不能修改索引。
文档操作
创建文档
这里就有点意思了,URL如下:
提出两个问题:
- _doc是文档名吗?不是,_doc可以理解为固定写法,表示在指定索引下创建一个文档。是的,文档的标识和命名啥的不是由你来指定的
- 请求是PUT吗?不是,是POST。因为ES认为你直接创建文档,没有指明文档的唯一标识,需要ES帮你指明和返回给你。那如何指定文档唯一标识呢?如下:
指定文档_id就可以发送PUT请求了。记得加上json请求体哦,以下示例:
{
"consigneeCardNo": "532233197906090036",
"consigneeCardType": "01",
"dataId": "4412578860562"
}
查询文档
根据文档ID查询
查询单个文档:Get, [http://localhost:9200/{索引名}/_doc/{文档id}]
返回文档对象,_source属性保存着我们新增的数据
查询索引下所有文档
查询索引下所有文档:Get, [http://localhost:9200/{索引名}/_search]
返回数据中hit属性为一个文档数组,每个文档的_source属性保存着我们新增的数据。
单条件查询(精准查询、模糊查询、分词查询)
-
方式一:URL拼接参数(不推荐,因为中文可能会乱码)
Get, [http://localhost:9200/{索引名}/_search?q=name:张三] -
方式二:请求体(GET也可以发送请求体,只是平时用的少,POST用的多)
Get, [http://localhost:9200/{索引名}/_search];
请求体:
{
"query":{
"match":{//不仅仅查询name为张三的,会进行精准、模糊、分词查询
"name": "张三"
}
}
}
完全匹配
{
"query":{
"match_phrase":{//查询name为张三的
"name": "张三"
}
}
}
字段高亮显示
{
"query":{
"match_phrase":{//查询name为张三的
"name": "张三"
}
},
"heightlight":{
"fields":{
"name":{}//name字符串里匹配关键字的部分高亮显示
}
}
}
查询的结果可能有:name=张三的,也可能name="张四",也可能是name="赵三"...
分页查询
Get, [http://localhost:9200/{索引名}/_search];
请求体:
{
"query":{
"match":{//不仅仅查询name为张三的,会进行精准、模糊、分词查询
"name": "张三"
}
},
"from":0,//from和size和limit 0,10一样效果
"size":10
}
查询指定字段
Get, [http://localhost:9200/{索引名}/_search];
请求体:
{
"query":{
"match":{//不仅仅查询name为张三的,会进行精准、模糊、分词查询
"name": "张三"
}
},
"from":0,//from和size和limit 0,10一样效果
"size":10,
"_source":["name"]//只查name属性
}
字段排序
Get, [http://localhost:9200/{索引名}/_search];
请求体:
{
"query":{
"match":{//不仅仅查询name为张三的,会进行精准、模糊、分词查询
"name": "张三"
}
},
"from":0,//from和size和limit 0,10一样效果
"size":10,
"_source":["name"],//只查name属性
"sort":{
"age": {
"order": "desc"
}
}
}
多条件查询(精准查询、模糊查询、分词查询)
Get, [http://localhost:9200/{索引名}/_search];
- 请求体:查询name为张三并且age=18岁的
{
"query":{
"bool":{
"must":[
{
"match": {
"name":"张三"
}
},
{
"match": {
"age":18
}
}
]
}
}
}
- 请求体:查询name为张三或者age=18岁的
{
"query":{
"bool":{
"should":[
{
"match": {
"name":"张三"
}
},
{
"match": {
"age":18
}
}
]
}
}
}
- 请求体:查询name为张三且age>18岁的
{
"query":{
"bool":{
"should":[
{
"match": {
"name":"张三"
}
}
],
"filter":{
"range":{
"age":{
"gt": 18
}
}
}
}
}
}
聚合查询
Get, [http://localhost:9200/{索引名}/_search];
- 分组:
{
"aggs":{//聚合操作
"name_group":{//聚合名称,任意起名
"terms":{//分组操作
"field": "name"//分组字段
}
}
}
}
- 平均值:
{
"aggs":{//聚合操作
"name_avg":{//聚合名称,任意起名
"avg":{//求平均值操作
"field": "name"//求平均值字段
}
}
}
}
修改文档
PUT: [http://localhost:9200/{索引名}/_doc/{文档id}];这个除了新增功能,还会全量覆盖,就是把之前的文档内容重新覆盖
POST: [http://localhost:9200/{索引名}/_update/{文档id}];修改的报文格式是有要求的,举例:
{
"doc": {//要更新的属性写在doc里
"name":"zhangsan",
"age": 14
}
}
删除文档
DELETE: [http://localhost:9200/{索引名}/_doc/{文档id}]
JavaApi操作ElasticSearch(非spring模式)
索引操作
新增索引
新增user索引:
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//获取索引操作客户端
IndicesClient indicesClient = client.indices();
CreateIndexResponse response = indicesClient.create(new CreateIndexRequest("user"), RequestOptions.DEFAULT);
if(response.isAcknowledged()){
System.out.println("成功");
}else {
System.out.println("失败");
}
client.close();
查询索引
查询user索引:
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
IndicesClient indicesClient = client.indices();
GetIndexResponse response = indicesClient.get(new GetIndexRequest("user"), RequestOptions.DEFAULT);
System.out.println(response.getAliases());
System.out.println(response.getMappings());
System.out.println(response.getSettings());
client.close();
删除索引
删除user索引:
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
IndicesClient indicesClient = client.indices();
AcknowledgedResponse response = indicesClient.delete(new DeleteIndexRequest("user"), RequestOptions.DEFAULT);
if(response.isAcknowledged()){
System.out.println("删除成功");
}else {
System.out.println("删除失败");
}
client.close();
文档操作
新增文档
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//插入文档
IndexRequest indexRequest = new IndexRequest();
indexRequest.index("user").id("1001");//插入到哪个索引,并指定文档ID
User user = new User();
user.setName("张三");
user.setAge(13);
indexRequest.source(XContentType.JSON, JSONUtil.toJsonStr(user));//设置插入的数据
IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);//发送
System.out.println(response.getResult());
client.close();
更新文档(局部更新)
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//更新文档
UpdateRequest updateRequest = new UpdateRequest();
updateRequest.index("user").id("1001");//更新到哪个索引哪个文档ID
User user = new User();
user.setName("张三");
user.setAge(18);
updateRequest.doc(XContentType.JSON, JSONUtil.toJsonStr(user));//设置更新数据
UpdateResponse response = client.update(updateRequest, RequestOptions.DEFAULT);//发送
System.out.println(response.getResult());
client.close();
查询文档
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//查询文档
GetRequest getRequest = new GetRequest();
getRequest.index("user").id("1001");//查询哪个索引哪个文档ID
GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);//发送
System.out.println(response.getSourceAsString());//查询的是我们的json数据
client.close();
删除文档
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
//查询文档
DeleteRequest deleteRequest = new DeleteRequest();
deleteRequest.index("user").id("1001");//删除哪个索引哪个文档ID
DeleteResponse response = client.delete(deleteRequest, RequestOptions.DEFAULT);//发送
System.out.println(response);
client.close();
标签:http,一篇,学会,9200,查询,索引,文档,Elasticsearch,name
From: https://www.cnblogs.com/ibcdwx/p/17150747.html