目录
基本语法
查询所有(match_all)
匹配查询(match)
多字段查询(multi_match)
精确匹配(term)
多词条精确匹配(terms)
结果过滤
直接指定字段
指定includes和excludes
布尔组合查询(bool)
must、must_not
should
filter
范围查询(range)
排序
单字段排序
多字段排序
分页
关键知识点总结
基本语法
POST /索引库名/_search
{
"query":{
"查询类型":{
"查询条件":"查询条件值"
}
}
}
- query:代表一个查询对象,里面可以有不同的查询属性;
- 查询类型:例如:
match_all
, match
,term
, range
等等;
- 查询条件:查询条件会根据类型的不同,写法也有差异。
查询所有(match_all)
POST shop/_search
{
"query": {
"match_all": {}
}
}
结果
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 5,
"max_score" : 1.0,
"hits" : [
{
"_index" : "shop",
"_type" : "goods",
"_id" : "5",
"_score" : 1.0,
"_source" : {
"title" : "京欣西瓜",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 10.6
}
},
{
"_index" : "shop",
"_type" : "goods",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"title" : "苹果",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 3.6
}
},
{
"_index" : "shop",
"_type" : "goods",
"_id" : "4",
"_score" : 1.0,
"_source" : {
"title" : "麒麟西瓜",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 20.6
}
},
{
"_index" : "shop",
"_type" : "goods",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"title" : "西瓜",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 15.6
}
},
{
"_index" : "shop",
"_type" : "goods",
"_id" : "3",
"_score" : 1.0,
"_source" : {
"title" : "香蕉",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 2.3
}
}
]
}
}
-
took:查询花费时间,单位是毫秒
-
time_out:是否超时
-
_shards:分片信息
-
hits:搜索结果总览对象
匹配查询(match)
POST /shop/_search
{
"query":{
"match":{
"title":"麒麟西瓜"
}
}
}
match
类型查询,会把查询条件进行分词,然后进行查询,多个词条之间是or的关系,例如通过查询条件为麒麟西瓜,分词后与西瓜相关的记录都会查到。
{
"took" : 11,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 3,
"max_score" : 1.219939,
"hits" : [
{
"_index" : "shop",
"_type" : "goods",
"_id" : "4",
"_score" : 1.219939,
"_source" : {
"title" : "麒麟西瓜",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 20.6
}
},
{
"_index" : "shop",
"_type" : "goods",
"_id" : "5",
"_score" : 0.2876821,
"_source" : {
"title" : "京欣西瓜",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 10.6
}
},
{
"_index" : "shop",
"_type" : "goods",
"_id" : "1",
"_score" : 0.2876821,
"_source" : {
"title" : "西瓜",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 15.6
}
}
]
}
}
如果想使用match进行更精确的查找,可以指定operator属性为and:
POST /shop/_search
{
"query": {
"match": {
"title": {
"query": "麒麟西瓜",
"operator": "and"
}
}
}
}
结果:
{
"took" : 11,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.219939,
"hits" : [
{
"_index" : "shop",
"_type" : "goods",
"_id" : "4",
"_score" : 1.219939,
"_source" : {
"title" : "麒麟西瓜",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 20.6
}
}
]
}
}
多字段查询(multi_match)
POST /shop/_search
{
"query": {
"multi_match": {
"query": "苹果",
"fields": ["title","subtitle"]
}
}
}
结果:
{
"took" : 7,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 1.2330425,
"hits" : [
{
"_index" : "shop",
"_type" : "goods",
"_id" : "2",
"_score" : 1.2330425,
"_source" : {
"title" : "苹果",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 3.6
}
},
{
"_index" : "shop",
"_type" : "goods",
"_id" : "v4e-03QB1qDLo16zF5gJ",
"_score" : 0.2876821,
"_source" : {
"title" : "红富士",
"images" : "http://image.xxx.com/12479122.jpg",
"price" : 6,
"subtitle" : "苹果"
}
}
]
}
}
精确匹配(term)
term
查询被用于精确值匹配,这些精确值可能是数字、时间、布尔或者那些未分词的字符串。
POST /shop/_search
{
"query":{
"term":{
"price":3.6
}
}
}
结果:
{
"took" : 4,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "shop",
"_type" : "goods",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"title" : "苹果",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 3.6
}
}
]
}
}
多词条精确匹配(terms)
terms
查询和 term 查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件,类似于mysql的in。
POST /shop/_search
{
"query":{
"terms":{
"price":[3.6,20.6]
}
}
}
结果:
{
"took" : 5,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 1.0,
"hits" : [
{
"_index" : "shop",
"_type" : "goods",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"title" : "苹果",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 3.6
}
},
{
"_index" : "shop",
"_type" : "goods",
"_id" : "4",
"_score" : 1.0,
"_source" : {
"title" : "麒麟西瓜",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 20.6
}
}
]
}
}
结果过滤
默认情况下,elasticsearch在搜索的结果中,会把文档中保存在_source
的所有字段都返回。如果我们只想获取其中的部分字段,我们可以添加_source
的过滤。
直接指定字段
POST /shop/_search
{
"_source": ["title","price"],
"query": {
"term": {
"price": 10.60
}
}
}
结果:
{
"took" : 5,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "shop",
"_type" : "goods",
"_id" : "5",
"_score" : 1.0,
"_source" : {
"price" : 10.6,
"title" : "京欣西瓜"
}
}
]
}
}
指定includes和excludes
- includes:来指定想要显示的字段;
- excludes:来指定不想要显示的字段。
POST /shop/_search
{
"_source": {
"includes":["title","price"]
},
"query": {
"term": {
"price": 3.6
}
}
}
POST /shop/_search
{
"_source": {
"excludes":["images","price"]
},
"query": {
"term": {
"price": 3.6
}
}
}
布尔组合查询(bool)
bool查询包含四种操作符,分别是must,should,must_not,query。它们均是一种数组,数组里面是对应的判断条件。
- must: 必须匹配,与and等价,贡献算分;
- must_not:必须不匹配,与not等价,常过滤子句用,但不贡献算分;
- should: 选择性匹配,至少满足一条,与 OR 等价,贡献算分;
- filter: 过滤子句,必须匹配,但不贡献算分。
must、must_not
POST /shop/_search
{
"query": {
"bool": {
"must": {
"match": {
"title": "西瓜"
}
},
"must_not": {
"match": {
"price": "20.6"
}
}
}
}
}
结果:
{
"took" : 8,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "shop",
"_type" : "goods",
"_id" : "5",
"_score" : 0.2876821,
"_source" : {
"title" : "京欣西瓜",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 10.6
}
},
{
"_index" : "shop",
"_type" : "goods",
"_id" : "1",
"_score" : 0.2876821,
"_source" : {
"title" : "西瓜",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 15.6
}
}
]
}
}
should
should类似于or,只要有一个条件满足即可:
POST /shop/_search
{
"query": {
"bool": {
"should": [{
"match": {
"title": "苹果"
}
},{
"match": {
"price": "20.6"
}
}]
}
}
}
结果:
{
"took" : 5,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 1.2330425,
"hits" : [
{
"_index" : "shop",
"_type" : "goods",
"_id" : "2",
"_score" : 1.2330425,
"_source" : {
"title" : "苹果",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 3.6
}
},
{
"_index" : "shop",
"_type" : "goods",
"_id" : "4",
"_score" : 1.0,
"_source" : {
"title" : "麒麟西瓜",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 20.6
}
}
]
}
}
filter
会查询对结果进行缓存,不会计算相关度,避免计算分值,执行速度非常快。
POST /shop/_search
{
"query": {
"bool": {
"filter": {
"term": {
"price": "20.6"
}
}
}
}
}
结果:_score属性为0
{
"took" : 18,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.0,
"hits" : [
{
"_index" : "shop",
"_type" : "goods",
"_id" : "4",
"_score" : 0.0,
"_source" : {
"title" : "麒麟西瓜",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 20.6
}
}
]
}
}
范围查询(range)
range
查询找出那些落在指定区间内的数字或者时间。
range
查询允许以下字符:
操作符 |
说明 |
gt |
大于 |
gte |
大于等于 |
lt |
小于 |
lte |
小于等于 |
POST /shop/_search
{
"query":{
"range": {
"price": {
"gte": 10,
"lt": 20
}
}
}
}
结果:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 1.0,
"hits" : [
{
"_index" : "shop",
"_type" : "goods",
"_id" : "5",
"_score" : 1.0,
"_source" : {
"title" : "京欣西瓜",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 10.6
}
},
{
"_index" : "shop",
"_type" : "goods",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"title" : "西瓜",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 15.6
}
}
]
}
}
排序
单字段排序
POST /shop/_search
{
"query": {
"range": {
"price": {
"gte": 5,
"lt": 20
}
}
},
"sort": [
{
"price": {
"order": "desc"
}
}
]
}
结果:
{
"took" : 6,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 3,
"max_score" : null,
"hits" : [
{
"_index" : "shop",
"_type" : "goods",
"_id" : "1",
"_score" : null,
"_source" : {
"title" : "西瓜",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 15.6
},
"sort" : [
15.6
]
},
{
"_index" : "shop",
"_type" : "goods",
"_id" : "5",
"_score" : null,
"_source" : {
"title" : "京欣西瓜",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 10.6
},
"sort" : [
10.6
]
},
{
"_index" : "shop",
"_type" : "goods",
"_id" : "v4e-03QB1qDLo16zF5gJ",
"_score" : null,
"_source" : {
"title" : "红富士",
"images" : "http://image.xxx.com/12479122.jpg",
"price" : 6,
"subtitle" : "苹果"
},
"sort" : [
6.0
]
}
]
}
}
多字段排序
POST /shop/_search
{
"query": {
"range": {
"price": {
"gte": 5,
"lt": 20
}
}
},
"sort": [
{
"price": {
"order": "desc"
}
},
{
"_score": {
"order": "desc"
}
}
]
}
分页
POST /shop/_search
{
"query": {
"match_all": {}
},
"size": 2,
"from": 0
}
- size:每页显示多少条;
- from:当前页起始索引, int start = (pageNum - 1) * size。
结果:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 6,
"max_score" : 1.0,
"hits" : [
{
"_index" : "shop",
"_type" : "goods",
"_id" : "5",
"_score" : 1.0,
"_source" : {
"title" : "京欣西瓜",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 10.6
}
},
{
"_index" : "shop",
"_type" : "goods",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"title" : "苹果",
"images" : "http://image.xxx.com/435252.jpg",
"price" : 3.6
}
}
]
}
}
关键知识点总结
- match 查询的时候,ES会根据你给定的字段提供合适的分析器,相当于模糊匹配,只包含其中一部分关键词就行;
- term 查询不会有分析器分析的过程,一般被用于精确值匹配,这些精确值可能是数字、时间、布尔或者那些未分词的字符串;
- must 为必须匹配,与and等价,贡献算分,查询时分数高的靠前;
- must_not 为必须不匹配,与not等价,常过滤子句用,但不贡献算分;
- should 为选择性匹配,至少满足一条,与 OR 等价,贡献算分;
- filter 为必须匹配,查询过程忽略算分,直接过滤匹配的数据,结果会被缓存,效率较高。