ES高级操作
结果过滤
默认情况下,elasticsearch在搜索的结果中,会把文档中保存在_source的所有字段都返回。
如果我们只想获取其中的部分字段,我们可以添加_source的过滤
直接指定字段
示例:
POST /heima/_search
{
"_source": ["title","price"],
"query": {
"term": {
"price": 2699
}
}
}
返回的结果:
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "heima",
"_type": "goods",
"_id": "3q3hTW0BTp_XthqB2lMR",
"_score": 1,
"_source": {
"price": 2699,
"title": "小米手机"
}
}
]
}
}
指定includes和excludes
我们也可以通过:
- includes:来指定想要显示的字段
- excludes:来指定不想要显示的字段
二者都是可选的。
示例:
POST /heima/_search
{
"_source": {
"includes":["title","price"]
},
"query": {
"term": {
"price": 2699
}
}
}
与下面的结果将是一样的:
POST /heima/_search
{
"_source": {
"excludes": ["images"]
},
"query": {
"term": {
"price": 2699
}
}
}
结果:
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "heima",
"_type": "goods",
"_id": "3q3hTW0BTp_XthqB2lMR",
"_score": 1,
"_source": {
"price": 2699,
"title": "小米手机"
}
}
]
}
}
高级查询
布尔组合(bool)
bool把各种其它查询通过must(与)、must_not(非)、should(或)的方式进行组合
GET /heima/_search
{
"query":{
"bool":{
"must": { "match": { "title": "小米" }},
"must_not": { "match": { "title": "电视" }},
"should": { "match": { "title": "手机" }}
}
}
}
结果:
{
"took": 134,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1.0884295,
"hits": [
{
"_index": "heima",
"_type": "goods",
"_id": "3q3hTW0BTp_XthqB2lMR",
"_score": 1.0884295,
"_source": {
"title": "小米手机",
"images": "http://image.leyou.com/12479122.jpg",
"price": 2699
}
}
]
}
}
范围查询(range)
range 查询找出那些落在指定区间内的数字或者时间
range查询允许以下字符:
| 操作符 | 说明 |
|---|---|
| gt | 大于 |
| gte | 大于等于 |
| lt | 小于 |
| lte | 小于等于 |
示例:
POST /heima/_search
{
"query":{
"range": {
"price": {
"gte": 3000,
"lt": 5000
}
}
}
}
结果:
{
"took": 7,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 1,
"hits": [
{
"_index": "heima",
"_type": "goods",
"_id": "3a3hTW0BTp_XthqB2lMR",
"_score": 1,
"_source": {
"title": "大米手机",
"images": "http://image.leyou.com/12479122.jpg",
"price": 3288
}
},
{
"_index": "heima",
"_type": "goods",
"_id": "363hTW0BTp_XthqB2lMR",
"_score": 1,
"_source": {
"title": "小米电视4A",
"images": "http://image.leyou.com/12479122.jpg",
"price": 4288
}
}
]
}
}
模糊查询(fuzzy)
我们新增一个商品:
POST /heima/goods/4
{
"title":"apple手机",
"images":"http://image.leyou.com/12479122.jpg",
"price":5899.00
}
fuzzy自动将拼写错误的搜索文本,进行纠正,纠正以后去尝试匹配索引中的数据
它允许用户搜索词条与实际词条出现偏差,但是偏差的编辑距离不得超过2:
POST /heima/_search
{
"query": {
"fuzzy": {
"title": "appla"
}
}
}
上面的查询,也能查询到apple手机
fuzziness,你的搜索文本最多可以纠正几个字母去跟你的数据进行匹配,默认如果不设置,就是2我们可以通过
POST /heima/_search
{
"query": {
"fuzzy": {
"title": {
"value": "applaa",
"fuzziness": 2
}
}
}
}
排序
单字段排序
sort 可以让我们按照不同的字段进行排序,并且通过order指定排序的方式
POST /heima/_search
{
"query": {
"match_all": {}
},
"sort": [
{"price": {"order": "desc"}}
]
}
多字段排序
假定我们想要结合使用 price和 _score(得分) 进行查询,并且匹配的结果首先按照价格排序,然后按照相关性得分排序:
POST /heima/_search
{
"query":{
"match_all":{}
},
"sort": [
{ "price": { "order": "desc" }},
{ "_score": { "order": "desc" }}
]
}
高亮
elasticsearch中实现高亮的语法比较简单:
POST /heima/_search
{
"query": {
"match": {
"title": "电视"
}
},
"highlight": {
"pre_tags": "<font color='pink'>",
"post_tags": "</font>",
"fields": {
"title": {}
}
}
}
在使用match查询的同时,加上一个highlight属性:
-
pre_tags:前置标签
-
post_tags:后置标签
-
fields:需要高亮的字段
- title:这里声明title字段需要高亮,后面可以为这个字段设置特有配置,也可以空
结果:
{
"took": 12,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.90204775,
"hits": [
{
"_index": "heima",
"_type": "goods",
"_id": "363hTW0BTp_XthqB2lMR",
"_score": 0.90204775,
"_source": {
"title": "小米电视4A",
"images": "http://image.leyou.com/12479122.jpg",
"price": 4288
},
"highlight": {
"title": [
"小米<font color='pink'>电视</font>4A"
]
}
}
]
}
}
分页
elasticsearch中实现分页的语法非常简单:
POST /heima/_search
{
"query": {
"match_all": {}
},
"size": 2,
"from": 0
}
size:每页显示多少条
from:当前页起始索引, int start = (pageNum - 1) * size;
小案例
制作测试数据
PUT /goods/fruit/1 { "name": "xiangjiao", "describe": "haochi tian", "price": 40, "producer": "feilvbin", "tags": [ "xiangjiao", "haochi" ] } PUT /goods/fruit/2 { "name":"pingguo", "describe":"cui", "price":60, "producer":"zhongguo", "tags":["haokan","xiang"] } PUT /goods/fruit/3 { "name":"lizi", "describe":"zide", "price":10, "producer":"zhongguo", "tags":["suan","tian"] } PUT /goods/fruit/4 { "name":"boluo", "describe":"getouda", "price":74, "producer":"malaxiya", "tags":["huang","youci"] } PUT /goods/fruit/5 { "name":"mihoutao", "describe":"suan", "price":45, "producer":"xinxilan", "tags":["lv","huang"] } PUT /goods/fruit/6 { "name":"xigua", "describe":"haochi", "price":109, "producer":"zhongguo", "tags":["da","haochi"] }
查询所有数据
GET goods/fruit/_search
{
"query": {
"match_all": {}
}
}

排序查询
GET goods/fruit/_search
{
"query": {
"match": {
"name": "pingguo"
}
},
"sort": {
"price": {
"order": "asc"
}
}
}
每页显示2条数据,无序的话,按照默认排序
GET goods/fruit/_search
{
"query": {
"match": {
"name": "pingguo"
}
},
"sort": {
"price": {
"order": "asc"
}
},
"from": 0,
"size": 2
}
使用 “_source” 查询指定字段的数据
GET goods/fruit/_search
{
"query": {
"match_all": {}
},
"_source": ["name", "producer"]
}

bool查询
bool的方式,根据指定字段查询数据。
GET goods/fruit/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "pingguo"
}
}
]
}
}
}
bool多条件查询,相当于sql的and语句。
GET goods/fruit/_search { "query": { "bool": { "must": [ { "match": { "name": "pingguo" } }, { "match": { "producer": "zhongguo" } } ] } } }

bool多条件或查询,相当于sql的or语句
GET goods/fruit/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"name": "pingguo"
}
},
{
"match": {
"producer": "zhongguo"
}
}
]
}
}
}

bool多条件非查询,相当于sql的not语句
GET goods/fruit/_search
{
"query": {
"bool": {
"must_not": [
{
"match": {
"name": "pingguo"
}
},
{
"match": {
"producer": "zhongguo"
}
}
]
}
}
}

按条件查询
查询name是pingguo的,然后价钱大于100的数据(里可以使用should但是不建议使用should,会出现异常错误)
GET goods/fruit/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "pingguo"
}
}
],
"filter": [
{
"range": {
"price": {
"gt": 100
}
}
}
]
}
}
}

短语检索
通过检索数组类型的数据,可直接通过全文检索,匹配多个值,通过空格间隔。
GET goods/fruit/_search
{
"query": {
"match": {
"tags": "da lv"
}
}
}

短语匹配,就像 match 查询对于标准全文检索是一种最常用的查询一样,当你想找到彼此邻近搜索词的查询方法时,就会想到 match_phrase 查询。
GET goods/fruit/_search
{
"query": {
"match_phrase": {
"name": "pingguo"
}
}
}
高亮显示(highlight)
GET goods/fruit/_search
{
"query": {
"match": {
"name": "pingguo"
}
},
"highlight": {
"pre_tags": "<b style='color: red'>",
"post_tags": "</b>",
"fields": {
"name": {}
}
}
}
聚合函数(先查询,在聚合,分段式)
查询出来的数据,选择指定字段计算平均值,例如计算价钱平均值。 sum 总数,avg 平均值
前20的平局值
GET goods/fruit/_search
{
"from": 0,
"size": 20,
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}

默认会同时展示计算结果与查询出来的数据,如果不想要查询出来的数据,将 size 设置为0

bool查询后,进行聚合函数处理(查询苹果价格大于100的价格总数)
GET goods/fruit/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "pingguo"
}
}
],
"filter": [
{
"range": {
"price": {
"gte": 100
}
}
}
]
}
},
"aggs": {
"c": {
"sum": {
"field": "price"
}
}
}
}

分段查询后,进行聚合函数处理
GET goods/_search
{
"size": 0,
"aggs": {
"f": {
"range": {
"field": "price",
"ranges": [
{
"from": 0,
"to": 50
},
{
"from": 50,
"to": 100
},
{
"from": 100,
"to": 150
}
]
},
"aggs": {
"sum_price": {
"sum": {
"field": "price"
}
}
}
}
}
}
输出结果如下
{ "took" : 11, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 7, "max_score" : 0.0, "hits" : [ ] }, "aggregations" : { "f" : { "buckets" : [ { "key" : "0.0-50.0", "from" : 0.0, "to" : 50.0, "doc_count" : 3, "sum_price" : { "value" : 95.0 } }, { "key" : "50.0-100.0", "from" : 50.0, "to" : 100.0, "doc_count" : 2, "sum_price" : { "value" : 134.0 } }, { "key" : "100.0-150.0", "from" : 100.0, "to" : 150.0, "doc_count" : 2, "sum_price" : { "value" : 218.0 } } ] } } }
mapping
查询mapping
GET goods/_mapping

新建mappings
dynamic的三个参数
-
1. false 不会为新增的字段数据不会创建索引(也就是用不存在mapping中的字段检索是检索不出来的)
-
2. true 会为所有数据属性创建索引,包括新建的字段属性
-
3. strict 必须添加指定的属性,添加动态属性的时候,会报错。
PUT my_index1
{
"mappings": {
"a": {
"dynamic": false,
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "long"
}
}
}
}
}
copy_to属性
copy_to属性,把当前属性的值复制给指定的字段
PUT my_index2
{
"mappings": {
"doc": {
"dynamic": false,
"properties": {
"first_name": {
"type": "text",
"copy_to":"full_name"
},
"last_name": {
"type": "lotextng"
},
"full_name": {
"type": "lotextng"
}
}
}
}
}
index属性
index属性,默认为true,如果设置为false,则当前属性不能被创建索引。及不能通过当前属性进行数据的筛选、搜索、查询等操作
PUT my_index2
{
"mappings": {
"doc": {
"dynamic": false,
"properties": {
"first_name": {
"type": "text",
"index": true
},
"last_name": {
"type": "text",
"index": false
}
}
}
}
}
对象型属性
创建对象型数据
PUT my_index3/doc/2
{
"name": "tom",
"age": 11,
"add": {
"address": "bj",
"tel": "13333333333"
}
}
根据嵌套的属性数据进行过滤查询
GET my_index3/doc/_search
{
"query": {
"match": {
"add.address": "bj"
}
}
}

ik分词器
ik分词器是按照词来分,单个字查不出来,es默认是按照字来分单个汉子也能查出来
创建mapping
PUT my_index7
{
"mappings": {
"doc": {
"dynamic": false,
"properties": {
"content": {
"type": "text",
"analyzer":"ik_max_word"
}
}
}
}
}
添加数据
PUT my_index7/doc/1
{
"content":"今天是个好日子"
}
PUT my_index7/doc/2
{
"content":"心想的事儿都能成"
}
模糊查询
GET my_index7/_search
{
"query": {
"match": {
"content": "日子"
}
}
}

单个查不出来
GET my_index7/_search
{
"query": {
"match": {
"content": "日"
}
}
}
es默认的分词器
PUT my_index8
{
"mappings": {
"doc": {
"dynamic": false,
"properties": {
"content": {
"type": "text"
}
}
}
}
}
PUT my_index8/doc/1
{
"content":"心想的事儿都能成"
}
GET my_index8/_search
{
"query": {
"match": {
"content": "事"
}
}
}

ik 最粗粒度分词,内容文章类的使用,标题的使用细的分词粒度
_all 不用重复定义,全局通用
PUT my_index9/
{
"mappings": {
"doc": {
"_all": {
"analyzer": "ik_smart"
},
"properties": {
"content": {
"type": "text"
}
}
}
}
}
短语查询和前缀查询
中文来说尽量使用短语查询
GET my_index8/_search
{
"query": {
"match_phrase": {
"content": "心想"
}
}
}
类似上面
GET my_index8/_search
{
"query": {
"match_phrase_prefix": {
"content": "心想"
}
}
}

浙公网安备 33010602011771号