这里使用Kibana的Dev Tools来操作,方便查看。也可使用postman等工具,注意请求方式即可。Kibana的安装可以查看之前的文章Elasticsearch & Kibana环境安装(CentOS)
一. 索引操作
对比关系型数据库,创建索引就等同于创建数据库
1. 创建索引 (索引全部小写)
PUT /index
例:这里创建一个product索引
PUT /product
响应
{
"acknowledged"【响应结果】: true, #true 操作成功
"shards_acknowledged"【分片结果】: true, #分片操作成功
"index"【索引名称】: ""
}
#注意: 创建索引库的分片数默认 1 片, 在 7.0 .0 之前的 Elasticsearch 版本中, 默认 5 片
2. 查询索引
GET /index
例:查询product索引
GET /product
响应
{
"product"【索引名】: {
"aliases"【别名】: {},
"mappings"【映射】: {},
"settings"【设置】: {
"index"【设置 - 索引】: {
"creation_date"【设置 - 索引 - 创建时间】: "",
"number_of_shards"【设置 - 索引 - 主分片数量】: "",
"number_of_replicas"【设置 - 索引 - 副分片数量】: "",
"uuid"【设置 - 索引 - 唯一标识】: "",
"version"【设置 - 索引 - 版本】: {
"created": ""
},
"provided_name"【设置 - 索引 - 名称】: ""
}
}
}
}
3. 删除索引
DELETE /index
例:删除product索引
DELETE /product
二. 文档操作
文档可以类比为关系型数据库中的表数据,添加的数据格式为 JSON 格式
1. 插入数据
PUT /index/_doc/id
{
Json数据
}
例:这里在product中插入测试数据
PUT /product/_doc/1
{
"name" : "xiaomi phone",
"desc" : "shouji zhong de zhandouji",
"price" : 3999,
"tags": [ "xingjiabi", "fashao", "buka" ]
}
PUT /product/_doc/2
{
"name" : "xiaomi nfc phone",
"desc" : "zhichi quangongneng nfc,shouji zhong de jianjiji",
"price" : 4999,
"tags": [ "xingjiabi", "fashao", "gongjiaoka" ]
}
PUT /product/_doc/3
{
"name" : "nfc phone",
"desc" : "shouji zhong de hongzhaji",
"price" : 2999,
"tags": [ "xingjiabi", "fashao", "menjinka" ]
}
PUT /product/_doc/4
{
"name" : "xiaomi erji",
"desc" : "erji zhong de huangmenji",
"price" : 999,
"tags": [ "low", "bufangshui", "yinzhicha" ]
}
PUT /product/_doc/5
{
"name" : "hongmi erji",
"desc" : "erji zhong de kendeji",
"price" : 399,
"tags": [ "lowbee", "xuhangduan", "zhiliangx" ]
}
响应
{
"_index"【索引】: "",
"_type"【类型 - 文档】: "",
"_id"【唯一标识】: "", #可以类比为 MySQL 中的主键,没有指定的话随机生成
"_version"【版本】: ,
"result"【结果】: "created", #这里的 create 表示创建成功
"_shards"【分片】: {
"total"【分片 - 总数】: 2,
"successful"【分片 - 成功】: 1,
"failed"【分片 - 失败】: 0
},
"_seq_no": 0,
"_primary_term": 1
}
2. 修改数据
PUT方式会全量替换的修改
PUT /index/_doc/id
{
json数据
}
例:通过id修改price的值
PUT /product/_doc/1
{
"name" : "xiaomi phone",
"desc" : "shouji zhong de zhandouji",
"price" : 33999,
"tags": [ "xingjiabi", "fashao", "buka" ]
}
POST的方式可以指定字段修改
POST /index/_doc/id/_update
{
"doc":{
json数据
}
}
例:通过id修改price的值
POST /product/_doc/1/_update
{
"doc":{
"price":333999
}
}
3. 删除数据
ES中的删除是逻辑删除
DELETE /index/_doc/id
例:删除id为1的数据
DELETE /product/_doc/1
4. 查询数据
查询有两种方式,一种是URL带参如GET /product/_search?q=name:xiaomi
的方式,另一种是使用JSON作为请求体,第一种方式可能会出现中文乱码等问题,不常用。下面主要以第二种方式进行演示。
4.1.1查全部1(URL带参方式)
GET /product/_doc/_search
4.1.2查全部2(JSON请求体方式)
GET /product/_search
{
"query": {
"match_all": {}
}
}
4.2查id 【查id为1的】
GET /product/_doc/1
4.3.1匹配查询1 【查name匹配xiaomi】(URL带参方式)
GET /product/_search?q=name:xiaomi
4.3.2匹配查询2 【查name匹配xiaomi】(JSON请求体方式)
ES会在插入数据时进行分词(默认情况下。具体和映射有关。下面映射小结详细说明)。
match
匹配类型查询,会把查询条件进行分词,然后进行查询,多个词条之间是 or 的关系。
match_phrase
则时完全匹配,查询的关键字和字段值完全相同才能查到。
multi_match
与 match
类似,不同的是它可以在多个字段中查询。
term
查询,精确的关键词匹配查询,不对查询条件进行分词。
terms
查询和 term
查询一样,但它允许你指定多值进行匹配。
GET /product/_search
{
"query": {
"match": {
"name": "xiaomi"
}
}
}
响应
{
"took【查询花费时间,单位毫秒】": ,
"timed_out【是否超时】": false,
"_shards【分片信息】": {
"total【总数】": 1,
"successful【成功】": 1,
"skipped【忽略】": 0,
"failed【失败】": 0
},
"hits【搜索命中结果】": {
"total"【搜索条件匹配的文档总数】: {
"value"【总命中计数的值】: 2,
"relation"【计数规则】: "eq"# eq 表示计数准确, gte 表示计数不准确
},
"max_score【匹配度分值】": 1.0,
"hits【命中结果集合】": [
....
}
]
}
}
4.4分页查询 【从第1条开始,每页2条】
from
:当前页的起始索引,默认从 0 开始。 from = (pageNum - 1) * size
size
:每页显示多少条
GET /product/_search
{
"query": {
"match_all": {}
},
"from": 0,
"size": 2
}
4.5查询指定字段 【查询name,price两个字段】
默认情况下,ES在搜索的结果中,会把文档中保存在_source 的所有字段都返回。如果我们只想获取其中的部分字段,我们可以添加_source 的过滤.
也可以通过:
includes:来指定想要显示的字段
excludes:来指定不想要显示的字段
GET /product/_search
{
"query": {
"match_all": {}
},
"from": 0,
"size": 2,
"_source": ["name","price"]
}
4.6排序 【按price倒叙】
GET /product/_search
{
"query": {
"match_all": {}
},
"_source": ["name","price"],
"sort": [
{
"price": {
"order": "desc"
}
}
]
}
4.7多条件查询
bool
把各种其它查询通过must
(必须 )、must_not
(必须不)、should
(应该)的方
式进行组合
4.7.1条件都满足(and查询)【查name匹配xiaomi 且 tags匹配fashao】
GET /product/_search
{
"query": {
"bool": { //条件
"must": [ //全部满足
{
"match": {
"name": "xiaomi"
}
},
{
"match": {
"tags": "fashao"
}
}
]
}
}
}
4.7.2条件满足其一(or查询)【查name匹配xiaomi 或 tags匹配fashao】
GET /product/_search
{
"query": {
"bool": {
"should": [ //满足其一
{
"match": {
"name": "xiaomi"
}
},
{
"match": {
"tags": "fashao"
}
}
]
}
}
}
4.8范围查询 【查price在大于1000小于3000之间的】
range
查询找出那些落在指定区间内的数字或者时间。range
查询允许以下字符
操作符 | 说明 |
---|---|
gt | 大于 > |
gte | 大于等于 >= |
lt | 小于 < |
lte | 小于等于 <= |
GET /product/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"name": "xiaomi"
}
},
{
"match": {
"tags": "fashao"
}
}
],
"filter": [ //过滤
{
"range": {
"price": {
"gte": 1000, //大于
"lte": 3000 //小于
}
}
}
]
}
}
}
4.9查询高亮显示【name字段高亮】
ES可以对查询内容中的关键字部分,进行标签和样式(高亮)的设置。
在使用 match
查询的同时,加上一个highlight
属性:
pre_tags
:前置标签
post_tags
:后置标签
fields
:需要高亮的字段
title
:这里声明 title 字段需要高亮,后面可以为这个字段设置特有配置,也可以空
GET /product/_search
{
"query": {
"match": {
"name": "xiaomi"
}
},
"highlight": {
"pre_tags": "",
"post_tags": "",
"fields": {
"name": {}
}
}
}
4.10聚合查询
聚合允许使用者对 es 文档进行统计分析,类似与关系型数据库中的 group by,当然还有很
多其他的聚合,例如取最大值、平均值等等。
4.10.1分组查询 【用price分组查询】
GET /product/_search
{
"aggs": { //聚合操作
"price_group": { //名称,自定义起名
"terms": { //分组
"field": "price" //分组的字段
}
}
},
"size": 0 //不查原始数据,去掉会查出原数据
}
4.10.2平均数查询 【查price的平均数】
GET /product/_search
{
"aggs": {
"price_avg": {
"avg": { //平均值
"field": "price"
}
}
},
"size": 0
}
三. 映射关系
在上面我们提到ES在插入数据时会进行分词,但具体某些字段需不需要分词是可以控制的。类似于数据库(database)中的表结构(table)创建数据库表需要设置字段名称,类型,长度,约束等;索引库也一样,需要知道这个类型下有哪些字段,每个字段有哪些约束信息,这就叫做映射(mapping)。
1. 创建映射
PUT /user //创建user索引用于测试
PUT /user/_mapping
{
"properties":{
"name":{
"type":"text", //text类型会被分词
"index":true //index为true会被索引
},
"sex":{
"type":"keyword", //keyword不会被分词
"index":true
},
"tel":{
"type":"keyword",
"index":false
}
}
}
可以使用GET /user/_mapping
查询刚创建的映射
下面测试一下映射的效果
首先添加一条测试数据
PUT /user/_create/1
{
"name":"张三",
"sex":"男性",
"tel":"13311111111"
}
进行查询
这里sex为男性,则可以查到数据
以上就是映射关系的操作和对查询的影响。