elasticsearch文档
创建文档
索引创建完毕,就需要创建文档
来添加数据。这里的文档可以理解为关系型数据库中表数据,添加的数据格式需要是JSON格式
在apipost中,向ES服务器发POST请求:http://localhost:9200/shopping/_doc
_doc
就表示文档数据,shopping
是已创建成功的索引
创建文档必须要有请求体内容,不然还会提示request body is required
请求体内容:
{
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":3999.00
}
这里创建文档的请求必须是POST
请求后,ES服务器响应:
{
"_index": "shopping", //索引
"_type": "_doc", //类型-文档
"_id": "MjyZlIABvQ1CdPxaiVJR", //主键标识,随机生成
"_version": 1, //版本
"result": "created", //created表示创建成功
"_shards": { //分片
"total": 2, //分片-总数
"successful": 1, //分片-成功
"failed": 0 //分片-失败
},
"_seq_no": 0,
"_primary_term": 1
}
上面创建的文档,没有指定数据唯一性标识,默认情况下, 是ES服务器随机生成的。如果需要自定义的唯一性标识,只需在创建文档请求的URL指定:http://localhost:9200/shopping/_doc/1
注意:如果增加数据时明确数据主键,请求方式可以是PUT
_doc
可以用_create
替代:
查看文档
查看文档时需要指定文档的唯一标识,类似于mysql的主键查询
在apipost中,向ES服务器发GET请求:http://localhost:9200/shopping/_doc/1
请求后,ES服务器响应:
{
"_index": "shopping", //索引
"_type": "_doc", //文档类型
"_id": "1", //主键id
"_version": 1, //版本
"_seq_no": 1,
"_primary_term": 1,
"found": true,
"_source": { //文档源信息
"title": "小米手机",
"category": "小米",
"images": "http://www.gulixueyuan.com/xm.jpg",
"price": 3999
}
}
修改文档
在apipost中,向ES服务器发POST请求:http://localhost:9200/shopping/_doc/1
这个请求URL地址同创建文档是一样的,如果请求体发生变化,则会将原有的数据内容覆盖
请求体:
{
"title": "华为手机",
"category": "华为",
"images": "http://www.gulixueyuan.com/hw.jpg",
"price": 4999
}
注意:这个请求体的参数要写全,比如只有title的话,那么数据就会被修改只有title了,其他数据都会丢失
请求后,ES服务器响应:
updated
表示数据被更新
再次发送#查看文档#请求:
修改字段
修改文档时,也可以只修改某一数据的局部数据
在apipost中,向ES服务器发POST请求:http://localhost:9200/shopping/_update/1
请求体内容:
{
"doc": {
//这个title字段是文档中已有的才会覆盖,如果文档中没有该字段就会新增一个属性
"title": "华为Mate 10"
}
}
请求后,ES服务器响应:
再去调用查看文档API,文档数据已更新
删除文档
删除文档不会立即从磁盘上移除,只是标记成已删除,即逻辑删除。
在apipost中,向ES服务器发送DELETE请求:http://localhost:9200/shopping/_doc/1
请求后,ES服务器响应:
再去调用查看文档API,文档会提示已不存在
如果是删除一个不存在的文档,同样也会提示文档不存在
条件删除
上面的文档删除,是根据文档的唯一标识进行删除;在实际开发中,需要根据条件对多数据进行删除
先调用创建文档API分别添加多条数据到ES:
{
"title":"小米手机1",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":1999
}
{
"title":"小米手机2",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":2999
}
{
"title":"小米手机3",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":3999
}
在apipost中,向ES服务器发POST请求:http://localhost:9200/shopping/_delete_by_query
请求体内容:
{
"query": {
"match": {
"price": 3999 //删除price为3999的文档
}
}
}
请求后,ES服务器响应:
全部删除
在apipost中,向ES服务器发POST请求:http://localhost:9200/shopping/_delete_by_query
请求体内容:
{
"query": {
"match_all": {}
}
}
全部查询
除了通过文档的唯一标识查询指定文档外,还可以使用_search
查询全部文档
在apipost中,向ES服务器发GET请求:http://localhost:9200/shopping/_search
请求体,直接发请求也是查询所有,不加请求体也行
{
//query就可以理解为,拼接查询条件,和mysql的where一样
//query代表一个查询对象,里面可以有不同的查询属性
"query": {
"match_all": {} //表示查询所有
}
}
query
: query 代表一个查询对象,里面可以有不同的查询属性
match_all
:查询类型,
例如:match_all
代表查询所有,match
根据字段条件匹配查询,multi_match
支持多个字段条件匹配查询-满足其中任意条件即符合,term
用于精确匹配-不分词,等等等等
请求后,ES服务器响应:结果集合有多条记录
{
"took【查询花费时间,单位毫秒】": 1116,
"timed_out【是否超时】": false,
"_shards【分片信息】": {
"total【总数】": 1,
"successful【成功】": 1,
"skipped【忽略】": 0,
"failed【失败】": 0
},
"hits【搜索命中结果】": {
"total【搜索条件匹配的文档总数】": {
"value【总命中计数的值】": 3,
"relation【计数规则】": "eq" //# eq 表示计数准确, gte 表示计数不准确
},
"max_score【匹配度分值】": 1,
"hits【命中结果集合】": []
}
}
匹配查询
match
匹配类型查询,会把查询条件进行分词,然后进行查询,多个分词的词条之间的or的关系
分词的意思:
加入es文档数据存储了 "小米手机" "华为手机"
那么"小米手机"和"华为手机"就会被ES的分词器默认分为:小米、手机、华为、手机 (可能会分的更细,到单字)
这样我们match的查询条件是小米手机,也会把华为手机这个结果查询到
在apipost中,向ES服务器发GET请求:http://localhost:9200/shopping/_search
{
"query": {
"match": {
"category": "华为"
}
}
}
请求后,ES服务器响应:
多字段匹配查询
multi_match
和match
类似,multi_match
支持多个字段查询
在apipost中,向ES服务器发GET请求:http://localhost:9200/shopping/_search
{
"query": {
"multi_match": {
"query": "小米",
"fields": ["title", "category"]
}
}
}
fields
为查询的字段集合
请求后,ES服务器响应:
关键字精确查询
term
查询,精确的关键字匹配查询,不会对查询条件进行分词,match
会对关键字分词。
在apipost中,向ES服务器发GET请求:http://localhost:9200/shopping/_search
{
"query": {
"term": {
"category.keyword": {
"value": "华为"
}
}
}
}
或者
{
"query": {
"term": {
"category.keyword": "华为"
}
}
}
注意:term在用于字符串类型的字段查询时,会查询不到记录,因为es会给每个字段进行分词然后建立倒排索引,为了满足需求达到精确查询,需要将字段的type设置为keyword
请求后,ES服务器响应:
多关键字精确查询
terms
查询和term
查询一样,可以实现多值进行匹配查询。类似于mysql的in
。
在apipost中,向ES服务器发GET请求:http://localhost:9200/shopping/_search
{
"query": {
"terms": {
"category.keyword": ["小米", "华为"]
}
}
}
请求后,ES服务器响应:
指定查询字段
默认情况下,ES会把文档中保存在_source
属性里面的所有字段返回,类似于mysql的select *
。
如果我们只需要获取部分字段,可以对_source
进行过滤
在apipost中,向ES服务器发GET请求:http://localhost:9200/shopping/_search
{
"_source": ["title", "price"], //集合里面的就是指定返回的字段
"query": {
"terms": {
"categroy.keyword": ["华为"]
}
}
}
请求后,ES服务器响应:_source只有price和title
过滤字段
includes
:指定想要显示的字段
exclueds
:指定不想要显示的字段
在apipost中,向ES服务器发GET请求:http://localhost:9200/shopping/_search
includes
{
"_source": {
"includes": ["category"]
},
"query": {
"terms": {
"category.keyword": ["华为"]
}
}
}
请求后,ES服务器响应:
excludes
{
"_source": {
"excludes": ["category", "price"]
},
"query": {
"terms": {
"category.keyword": ["华为"]
}
}
}
请求后,ES服务器响应:
分页查询
查询全部文档API提供了查询全部文档数据,但是一次性查询全部文档数据量会特别大,所以同传统的数据库一样,ES也支持分页查询,
请求体中的分页关键字:
from
:当前页的起始索引,默认从0开始。from = (pageNum - 1) * size
size
:每页显示多少条
在apipost中,向ES服务器发GET请求:http://localhost:9200/shopping/_search
请求体:
{
//如果没有别的属性条件,query可不加
"query": {
"match_all": {} //表示查询所有
},
"from": 0,
"size": 1
}
请求后,ES服务器响应:
查询排序
sort
可以让我们按照不同的字段进行排序,通过order
来实现升序(asc)和降序(desc)
单字段排序
在apipost中,向ES服务器发GET请求:http://localhost:9200/shopping/_search
请求体:
{
"query": {
"match_all": {} //查询全部可省略这个
},
"sort": [{
"price": {
"order": "desc"
}
}]
}
请求后,ES服务器响应:
多字段排序
// todo
范围查询
range
查询可以找出指定区间内的数据,比如时间范围,年龄范围,价格范围等等等等
range
允许以下字符:
操作符 | 说明 |
---|---|
gt | 大于 |
gte | 大于等于 |
lt | 小于 |
lte | 小于等于 |
在apipost中,向ES服务器发GET请求:http://localhost:9200/shopping/_search
请求体:
{
"query": {
"range": {
"price": {
"gte": 1000,
"lte": 2000
}
}
}
}
请求后,ES服务器响应:
组合查询
bool
可以把各种查询条件通过must
(必须)、must_not
(必须不)、should
(应该)的方式组合。
在apipost中,向ES服务器发GET请求:http://localhost:9200/shopping/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"title": "华为"
}
}
],
"must_not": [
{
"match": {
"price": "4999"
}
}
],
"should": [
{
"match": {
"category": "华为"
}
}
]
}
}
}
请求后,ES服务器响应:
模糊查询
返回包含与搜索字词相似字词的文档。需要使用fuzzy
。
为了找到相似的术语,fuzzy
查询会在指定的编辑距离内创建一组搜索词的所有可能的变体或者扩展。然后查询返回每个扩展的完全匹配。
编辑距离是指将一个术语转换成另一个术语所需的一个字符更改的次数。 这些更改可以包括:
- 更改字符:box → fox
- 删除字符:black → lack
- 插入字符:sic → sick
- 转置相邻字符:act → cat
通过fuzziness
修改编辑距离。一般使用默认值AUTO,根据术语的长度生成编辑距离。
在apipost中,向ES服务器发GET请求:http://localhost:9200/shopping/_search
{
"query": {
"fuzzy": {
"title": "手机"
}
}
}
高亮查询
在进行关键字搜索时,搜索出的内容中的关键字会显示不同的颜色,称之为高亮。
elasticsearch可以对查询内容中的关键字部分,进行标签和样式(高亮)的设置。在使用查询的同时,加上一个highlight
属性:
pre_tags
:前置标签post_tags
:后置标签fields
:需要高亮的字段
在apipost中,向ES服务器发GET请求:http://localhost:9200/shopping/_search
{
"query": {
"match": {
"title": "小米手机"
}
},
"highlight": {
"pre_tags": "<font color='red'>",
"post_tags": "</font>",
"fields": {
"title": {}
}
}
}
请求后,ES服务器响应:
聚合查询
聚合查询可以对es文档进行统计分析,取最大值、最小值、平均值等。
最大值max
对某个字段取最大值
在apipost中,向ES服务器发GET请求:http://localhost:9200/shopping/_search
{
"aggs": {
"max_price": {
"max": {
"field": "price"
}
}
},
"size": 0
}
aggs
:表示使用聚合查询max_price
:聚合查询的名称,可自定义max
:查询最大值field
:条件字段size
:0,表示只返回聚合结果,不返回具体的文档结果集
请求后,ES服务器响应:
最小值min
对某个字段取最小值
在apipost中,向ES服务器发GET请求:http://localhost:9200/shopping/_search
{
"aggs": {
"min_price": {
"min": {
"field": "price"
}
}
},
"size": 0
}
aggs
:表示使用聚合查询min_price
:聚合查询的名称,可自定义min
:查询最小值field
:条件字段size
:0,表示只返回聚合结果,不返回具体的文档结果集
请求后,ES服务器响应:
求和sum
对某个字段求和
在apipost中,向ES服务器发GET请求:http://loalhost:9200/shopping/_search
{
"aggs": {
"sum_price": {
"sum": {
"field": "price"
}
}
},
"size": 0
}
aggs
:表示使用聚合查询sum_price
:聚合查询的名称,可自定义sum
:求和field
:查询字段size
:0,表示只返回聚合结果,不返回具体的文档结果集
请求后,ES服务器响应:
平均值avg
对某个字段取平均值
在apipost中,向ES服务器发GET请求:http://localhsot:9200/shopping/_search
{
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
},
"size": 0
}
aggs
:表示使用聚合查询avg_price
:聚合查询的名称,可自定义avg
:平均值field
:查询条件size
:0,表示只返回聚合结果,不返回具体的文档结果集
请求后,ES服务器响应:
去重
对某个字段的值进行去重
在apipost中,向ES服务器发GET请求:http://localhost:9200/shopping/_search
{
"aggs": {
"distinct_category": {
"cardinality": {
"field": "category.keyword"
}
}
},
"size": 0
}
aggs
:表示使用聚合查询distinct_category
:聚合查询名称,可自定义cardinality
:去重基数field
:去重字段,如果字段是text类型,需要keyword
size
:0,表示只返回聚合结果,不返回具体的文档结果集
请求后,ES服务器响应:category
字段只有两个分类,华为和小米
stats聚合
对某个字段一次性返回count
、max
、min
、avg
和sum
五个指标
在apipost中,向ES服务器发GET请求:http://localhost:9200/shopping/_search
{
"aggs": {
"stats_price": {
"stats": {
"field": "price"
}
}
},
"size": 0
}
请求后,ES服务器响应:
桶聚合查询
桶聚相当于mysql中的group by
语句
terms分组统计
在apipost中,向ES服务器中发GET请求:http://localhost:9200/shopping/_search
{
"aggs": {
"groupby_category": {
"terms": {
"field": "category.keyword"
}
}
},
"size", 0
}
aggs
:表示聚合查询groupby_category
:聚合查询名称,可自定义terms
:精确字段分组统计field
:字段,text类型需要加keyword
请求后,ES服务器响应:
terms分组下再次聚合查询
在apipost中,向ES服务器发GET请求:http://localhost:9200/shopping/_search
{
"aggs": {
"groupby_category": {
"terms": {
"field": "category.keyword"
},
"aggs": {
"sum_price": {
"sum": { "field": "price" }
}
}
}
},
"size": 0
}
请求后,ES服务器响应: