RESTful API 操作elasticsearch (2)

x33g5p2x  于2021-08-23 转载在 Java  
字(21.2k)|赞(0)|评价(0)|浏览(361)

三 RESTful索引操作

在ES 中我们都使用Restful风格的API来操作ES;

3.1 创建索引

使用 PUT 操作来创建索引;

创建一个索引的books ;

localhost:9200/books

友情提示如果是想在 unix发送 put 请求 可以使用 curl 工具达到目的;比如本示例中的请求使用curl, curl 可以通过 -d 指定json参数;

curl -XPUT ‘localhost:9200/books?pretty’

默认情况下,创建的索引分片数量是 5 个,副本数量是 1 个。 通过body 为json形式发送数据即可改变分片大小!

{
	"settings": {
		"number_of_shards": 3,
		"number_of_replicas": 2
	}
}

3.2 查看所有索引

GET localhost:9200/_cat/indices?v

打印结果如下

表头含义
health当前服务器健康状态: green(集群完整) yellow(单点正常、集群不完整) red(单点不正常)
status索引打开、关闭状态
index索引名称
uuid索引编号
pri主分片数量
rep副本数量
docs.count可用文档数量
docs.deleted文档删除状态(逻辑删除)
store.size主分片和副分片整体占空间大小
pri.store.size主分片占空间大小

3.3 查看单个索引

向ES服务器发GET请求

GET localhost:9200/books

输出

{
    "books": {
        "aliases": {},
        "mappings": {},
        "settings": {
            "index": {
                "creation_date": "1618107843321",
                "number_of_shards": "1",
                "number_of_replicas": "1",
                "uuid": "VrE3TU0JQueUHELQUMOqOQ",
                "version": {
                    "created": "7080099"
                },
                "provided_name": "books"
            }
        }
    }
}

3.4 删除索引

向ES服务器发DELETE请求

DELETE localhost:9200/books

输出

{
    "acknowledged": true
}

3.5 关闭打开索引

向ES服务器发POST 请求;关闭索引后就无法向ES服务器写入和读取数据,直到再次打开;

POST localhost:9200/books/_close

结果

{
    "acknowledged": true,
    "shards_acknowledged": true,
    "indices": {
        "books": {
            "closed": true
        }
    }
}

打开索引

POST localhost:9200/books/_open

结果

{
    "acknowledged": true,
    "shards_acknowledged": true
}

四 RESTful文档操作

4.1 创建文档

在创建好索引的前提下,创建文档;如下示例创建的文档名称为_doc

POST localhost:9200/books/_doc

body 为

{
    "name":"知识追寻者传记",
    "category": "传记",
    "website": "https://zszxz.com/index",
    "price": "1998"
}

请求成功结果

{
    "_index": "books",
    "_type": "_doc",
    "_id": "jbryv3gBWoY-bzhxRsD7",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 0,
    "_primary_term": 1
}

其中含义如下

  • _index: 索引
  • _type : 类型
  • _id: 唯一编号
  • _version 版本
  • result: 结果,创建
  • _shards: 分片

默认情况下, ES会自动分配唯一索引给文档;如果需要自定义则按照如下示例,1 为id

POST localhost:9200/books/_doc/1

Body

{
    "name":"知识追寻者游记",
    "category": "游记",
    "website": "https://zszxz.com/index",
    "price": "998"
}

成功为created;

{
    "_index": "books",
    "_type": "_doc",
    "_id": "1",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 1,
    "_primary_term": 1
}

4.2 查看文档

发送 GET 请求

GET localhost:9200/books/_doc/1

结果

{
    "_index": "books",
    "_type": "_doc",
    "_id": "1",
    "_version": 1,
    "_seq_no": 1,
    "_primary_term": 1,
    "found": true,
    "_source": {
        "name": "知识追寻者游记",
        "category": "游记",
        "website": "https://zszxz.com/index",
        "price": "998"
    }
}

4.2 修改文档

发送PUT 请求

PUT localhost:9200/books/_doc/1

Body如下所示会覆盖整个文档

{
    "name":"知识追寻者游记",
    "category": "游记",
    "website": "https://zszxz.com",
    "price": "889"
}

结果为 update; 版本提示加1, successful 为1 ,成功1条;

{
    "_index": "books",
    "_type": "_doc",
    "_id": "1",
    "_version": 2,
    "result": "updated",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 2,
    "_primary_term": 1
}

如果想修改文档中的某个字段;比如 价格

发送POST 请求,但参数形式改变

POST localhost:9200/books/_update/1

Body

{
    "doc":{
        "price": "500"
    }
}

结果为update, successful 为1 ;

{
    "_index": "books",
    "_type": "_doc",
    "_id": "1",
    "_version": 2,
    "result": "updated",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 2,
    "_primary_term": 1
}

也可以通过 update_by_query方式来更新文档,其是使用脚本的方式更新文档;可以查阅官方地址

https://www.elastic.co/guide/en/elasticsearch/reference/7.12/docs-update-by-query.html进行学习;

4.3 删除文档

向ES服务器发送DELETE请求

DELETE localhost:9200/books/_doc/1

结果为delete, successful 为 1 表示删除一条成功;

{
    "_index": "books",
    "_type": "_doc",
    "_id": "1",
    "_version": 4,
    "result": "deleted",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 4,
    "_primary_term": 1
}

上面这样是根据id进行删除,如果想要按指定条件删除文档则使用delete by query方式;即查询删除方式来删除文档;

注意发送的是post 的亲求

POST localhost:9200/books/_delete_by_query

body

{
    "query":{
        "match": {
            "category": "游记"
        }
    }
}

结果为含删除该文档,注意此删除操作会影响整个_doc文档;

{
    "took": 14,
    "timed_out": false,
    "total": 1,
    "deleted": 1,
    "batches": 1,
    "version_conflicts": 0,
    "noops": 0,
    "retries": {
        "bulk": 0,
        "search": 0
    },
    "throttled_millis": 0,
    "requests_per_second": -1.0,
    "throttled_until_millis": 0,
    "failures": []
}

五 RESTful映射操作

映射数据结构

  • 字段名: 即映射规则的字段名称;
  • 类型:类型有String, Date, Numerical,Object,Array,Bool等; 其中 String 最为常用,其内部的text 表示可以分词,keyword 表示精确匹配;数字类型有int,flot,double,long;
  • 索引: index 表示是否可以用来被搜索,true 表示可以,false 表示不可以;
  • store:值为yes表示存储,为no表示不存储,默认为no;
  • analyzer:分词器

5.1 查看映射

GET localhost:9200/books/_mapping

5.2 定义映射

定义一个自定义的映射通常是在创建索引时定义;

新建一个事件索引

PUT localhost:9200/event

body为事件的映射, 字段 name 可以被检索分词, 字段address不可以被检索;

{
    "mappings": {
        "properties": {
            "name": {
                "type": "text",
                "index": true
            },
            "address": {
                "type": "keyword",
                "index": false
            }
        }
    }
}

查看定义的映射

5.3 扩展映射

已经定义好的映射是不能进行修改;但可以在原有映射的基础上扩展

PUT localhost:9200/event/_mapping

新增 2 个字段 分别是人物,精确查找;日期,并且进行格式化;

{
    "properties": {
        "figure": {
            "type": "keyword",
            "index": true
        },
        "date": {
            "type": "date",
            "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd"
        }
    }
}

执行结果

{
    "acknowledged": true
}

5.4 删除映射

删除映射只能通过删除索引来删除映射;

六 RESTful查询进阶

准备数据

POST localhost:9200/event/_doc/1

body1

{
    "name":"xuezai",
    "address": "北爱尔兰",
    "date": "2021-04-10 00:00:00",
    "figure": "小识"
}
POST localhost:9200/event/_doc/2

body2

{
    "name":"haixiao",
    "address": "东印度",
    "date": "2021-04-10 00:00:00",
    "figure": "小知"
}

6.1 查询所有文档

在文档后面加关键字 _search

GET localhost:9200/books/_doc/_search

输出

{
    "took": 2,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 1.0,
        "hits": [
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "2",
                "_score": 1.0,
                "_source": {
                    "name": "haixiao",
                    "address": "东印度",
                    "date": "2021-04-10 00:00:00",
                    "figure": "小知"
                }
            },
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "1",
                "_score": 1.0,
                "_source": {
                    "name": "xuezai",
                    "address": "北爱尔兰",
                    "date": "2021-04-10 00:00:00",
                    "figure": "小识"
                }
            }
        ]
    }
}

6.2 match匹配

match 匹配会进行匹配过滤,如果字段支持分词效果,则返回结果可以是匹配到的多条数据;所以默认情况下match 匹配是or 匹配

GET localhost:9200/event/_doc/_search

Body

{
    "query":{
        "match":{
            "name": "haixiao"
        }
    }
}

返回结果

{
    "took": 2,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 0.6931471,
        "hits": [
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "2",
                "_score": 0.6931471,
                "_source": {
                    "name": "haixiao",
                    "address": "东印度",
                    "date": "2021-04-10 00:00:00",
                    "figure": "小知"
                }
            }
        ]
    }
}

当参数为如下or条件时, 放回 name = "haixiao" 或者 name ="xuezai" 匹配到的数据

{
    "query": {
        "match": {
            "name": {
                "query": "haixiao, xuezai",
                "operator": "or"
            }
        }
    }
}

返回结果

{
    "took": 6,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 0.6931471,
        "hits": [
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "2",
                "_score": 0.6931471,
                "_source": {
                    "name": "haixiao",
                    "address": "东印度",
                    "date": "2021-04-10 00:00:00",
                    "figure": "小知"
                }
            },
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "1",
                "_score": 0.6931471,
                "_source": {
                    "name": "xuezai",
                    "address": "北爱尔兰",
                    "date": "2021-04-10 00:00:00",
                    "figure": "小识"
                }
            }
        ]
    }
}

当参数改如下and条件时, 则没有匹配到数据

{
    "query": {
        "match": {
            "name": {
                "query": "haixiao, xuezai",
                "operator": "and"
            }
        }
    }
}

match 匹配的衍生 ,multi_match 支持多字段匹配,使用参数格式如下

{
  "query": {
    "multi_match": {
        "query": "名称",
        "fields": ["字段1","字段2",...]
    }
  }
}

6.3 term 匹配

term 匹配为精确匹配;

GET localhost:9200/event/_doc/_search

Body

{
    "query":{
        "term":{
            "name":"xuezai"
        }
    }
}

匹配结果

{
    "took": 2,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 0.6931471,
        "hits": [
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "1",
                "_score": 0.6931471,
                "_source": {
                    "name": "xuezai",
                    "address": "北爱尔兰",
                    "date": "2021-04-10 00:00:00",
                    "figure": "小识"
                }
            }
        ]
    }
}

在tem后面加个 s 可以支持 多参数查询

{
    "query":{
        "terms":{
            "name": ["xuezai","haixiao"]
        }
    }
}

查询结果

{
    "took": 14,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 1.0,
        "hits": [
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "2",
                "_score": 1.0,
                "_source": {
                    "name": "haixiao",
                    "address": "东印度",
                    "date": "2021-04-10 00:00:00",
                    "figure": "小知"
                }
            },
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "1",
                "_score": 1.0,
                "_source": {
                    "name": "xuezai",
                    "address": "北爱尔兰",
                    "date": "2021-04-10 00:00:00",
                    "figure": "小识"
                }
            }
        ]
    }
}

6.4 指定返回字段

之前的查询默认都会将 "_source" 里面所有字段查询返回,如果需要指定返回字段,则需要在 "_source" 中指定返回的字段;

GET localhost:9200/event/_doc/_search

Body

{
    "query":{
        "terms":{
            "name": ["xuezai","haixiao"]
        }
    },
    "_source": ["name","address"]
}

返回结果

{
    "took": 19,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 1.0,
        "hits": [
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "2",
                "_score": 1.0,
                "_source": {
                    "address": "东印度",
                    "name": "haixiao"
                }
            },
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "1",
                "_score": 1.0,
                "_source": {
                    "address": "北爱尔兰",
                    "name": "xuezai"
                }
            }
        ]
    }
}

还可以指定 "_source" 中的 includes 显示字段,excludes 排除字段

body 如下 ,排除显示 name , address

{
    "query":{
        "terms":{
            "name": ["xuezai","haixiao"]
        }
    },
    "_source": {
        "excludes": ["name","address"]
    }
}

结果

{
    "took": 4,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 1.0,
        "hits": [
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "2",
                "_score": 1.0,
                "_source": {
                    "date": "2021-04-10 00:00:00",
                    "figure": "小知"
                }
            },
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "1",
                "_score": 1.0,
                "_source": {
                    "date": "2021-04-10 00:00:00",
                    "figure": "小识"
                }
            }
        ]
    }
}

6.5 bool 查询

bool 查询可以成为组合查询或者复合查询;通过must(必须,多个组合时为and )、must_not(必须不, 多个组合为not)、should(应该,多个组合时为or)的方式进行组合查询;

GET localhost:9200/event/_doc/_search

body

{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "xuezai"
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "name": "haixiao"
          }
        }
      ],
      "should": [
        {
          "match": {
            "figure": "小识"
          }
        }
      ]
    }
  }
}

查询结果

{
    "took": 26,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 1.3862942,
        "hits": [
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "1",
                "_score": 1.3862942,
                "_source": {
                    "name": "xuezai",
                    "address": "北爱尔兰",
                    "date": "2021-04-10 00:00:00",
                    "figure": "小识"
                }
            }
        ]
    }
}

6.6 range范围查询

range 范围查询即区间查询;

操作符说明
gt大于> 字段
gte大于等于>= 字段
lt小于< 字段
lte小于等于<= 字段
GET localhost:9200/event/_doc/_search

body

{
  "query": {
    "range": {
      "date": {
        "gte": "2021-04-10 00:00:00"
      }
    }
  }
}

返回结果

{
    "took": 15,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 1.0,
        "hits": [
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "2",
                "_score": 1.0,
                "_source": {
                    "name": "haixiao",
                    "address": "东印度",
                    "date": "2021-04-10 00:00:00",
                    "figure": "小知"
                }
            },
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "1",
                "_score": 1.0,
                "_source": {
                    "name": "xuezai",
                    "address": "北爱尔兰",
                    "date": "2021-04-10 00:00:00",
                    "figure": "小识"
                }
            }
        ]
    }
}

将 gte 改为 gt 则返回值无数据;

6.7 模糊查询

通配符的模糊查询 * 代表匹配任意字符串, ?表示匹配一个字符串;

GET

Body

{
  "query": {
    "wildcard": {
      "figure": {
        "value": "小*"
      }
    }
  }
}

结果

{
    "took": 52,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 1.0,
        "hits": [
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "2",
                "_score": 1.0,
                "_source": {
                    "name": "haixiao",
                    "address": "东印度",
                    "date": "2021-04-10 00:00:00",
                    "figure": "小知"
                }
            },
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "1",
                "_score": 1.0,
                "_source": {
                    "name": "xuezai",
                    "address": "北爱尔兰",
                    "date": "2021-04-10 00:00:00",
                    "figure": "小识"
                }
            }
        ]
    }
}

6.8 高亮查询

Elasticsearch 高亮查询需要使用到 highlight属性;

  • pre_tags:前置标签
  • post_tags:后置标签
  • fields:需要高亮的字段
GET localhost:9200/event/_doc/_search

Body

{
  "query": {
    "match": {
      "name": "haixiao"
    }
  },
  "highlight": {
    "pre_tags": "<font color='red'>",
    "post_tags": "</font>",
    "fields": {
      "name": {}
    }
  }
}

输出结果

{
    "took": 262,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 0.6931471,
        "hits": [
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "2",
                "_score": 0.6931471,
                "_source": {
                    "name": "haixiao",
                    "address": "东印度",
                    "date": "2021-04-10 00:00:00",
                    "figure": "小知"
                },
                "highlight": {
                    "name": [
                        "<font color='red'>haixiao</font>"
                    ]
                }
            }
        ]
    }
}

6.9 分页查询

分页查询 from 相当于页码 其计算公示 from = ( 页码 - 1 ) * size

GET localhost:9200/event/_doc/_search

Body

{
  "query": {
    "match_all": {}
  },
  "from": 1,
  "size": 1
}

查询第二页的一条数据结果

{
    "took": 6,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 1.0,
        "hits": [
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "1",
                "_score": 1.0,
                "_source": {
                    "name": "xuezai",
                    "address": "北爱尔兰",
                    "date": "2021-04-10 00:00:00",
                    "figure": "小识"
                }
            }
        ]
    }
}

6.10 聚合查询

Elasticsearch 的聚合查询需要使用到 aggs 参数 表示聚合函数; 比如 我有个字段 价格 为 price

那么求最小值的参数应如下

{
    "aggs":{
      "min_price ":{
        "min":{"field":"price "}
      }
    }
}

最大值参数如下

{
    "aggs":{
      "max_price ":{
        "max":{"field":"price "}
      }
    }
}

求和参数

{
    "aggs":{
      "sum_price ":{
        "sum":{"field":"price "}
      }
    }
}

求平均值参数

{
    "aggs":{
      "avg_price ":{
        "avg":{"field":"price "}
      }
    }
}

特殊的关键字 state能够返回 count,max,min,avg和sum五个指标

{
    "aggs":{
      "stats_price":{
        "stats":{"field":"price"}
      }
    }
}

特殊关键字cardinality去重,相当于MYSQL中的distinct关键字参数

{
    "aggs" : {
        "state_count" : {
            "cardinality" : {
                "field" : "price"
            }
        }
    }
}

6.11 桶聚合查询

桶聚和相当于MYSQL 中的group by语句

GET localhost:9200/event/_doc/_search

body

{
    "aggs":{
      "address_groupby":{
        "terms":{"field":"address"}
      }
    },
    "size":0
} 

这边设置 size 为 0 ,就可以不显示原始数据,否则会查询匹配原来的数据和分组数据;并且,被分组的字段必须为keyword类型;

{
    "took": 27,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": null,
        "hits": []
    },
    "aggregations": {
        "address_groupby": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
                {
                    "key": "东印度",
                    "doc_count": 1
                },
                {
                    "key": "北爱尔兰",
                    "doc_count": 1
                }
            ]
        }
    }
}

6.12 排序查询

指定关键字 order 为 desc降序,asc升序。

GET localhost:9200/event/_doc/_search

body

{
  "query": {
    "match": {
        "name":"xuezai"
    }
  },
  "sort": [{
    "address": {
        "order":"desc"
    }
  }]
}

返回结果

{
    "took": 19,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 1,
            "relation": "eq"
        },
        "max_score": null,
        "hits": [
            {
                "_index": "event",
                "_type": "_doc",
                "_id": "1",
                "_score": null,
                "_source": {
                    "name": "xuezai",
                    "address": "北爱尔兰",
                    "date": "2021-04-10 00:00:00",
                    "figure": "小识"
                },
                "sort": [
                    "北爱尔兰"
                ]
            }
        ]
    }
}

相关文章