文章目录
数据准备工作
文档数据mapping如下:
{
"user" : {
"mappings" : {
"people" : {
"properties" : {
"age" : {
"type" : "integer"
},
"hobby" : {
"type" : "text",
"analyzer" : "ik_max_word"
},
"mail" : {
"type" : "keyword"
},
"name" : {
"type" : "text"
}
}
}
}
}
}
hobby字段使用了ik中文分词
文档数据如下:
1.1、term查询
查询某个字段里含有某个关键词的文档,对==查询关键词作为一个整体去查询 ==,主要用于搜索数字、日期、布尔值、未经分词的字符串
GET /user/_search
{
"query": {
"term": {
"age": {
"value": "21"
}
}
}
}
## 响应
{
"took" : 59,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "user",
"_type" : "people",
"_id" : "hWk5jHQBzgrkYgRNOrUU",
"_score" : 1.0,
"_source" : {
"name" : "李四",
"age" : 21,
"mail" : "222@qq.com",
"hobby" : "羽毛球、乒乓球、足球、篮球"
}
}
]
}
}
1.2、terms查询
与term查询相似,但terms允许指定多个匹配条件
举例:查询age=21,23的数据
GET /user/_search
{
"query": {
"terms": {
"age": [
"21",
"23"
]
}
}
}
## 响应
{
"took" : 262,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 1.0,
"hits" : [
{
"_index" : "user",
"_type" : "people",
"_id" : "hWk5jHQBzgrkYgRNOrUU",
"_score" : 1.0,
"_source" : {
"name" : "李四",
"age" : 21,
"mail" : "222@qq.com",
"hobby" : "羽毛球、乒乓球、足球、篮球"
}
},
{
"_index" : "user",
"_type" : "people",
"_id" : "h2k5jHQBzgrkYgRNOrUU",
"_score" : 1.0,
"_source" : {
"name" : "赵六",
"age" : 23,
"mail" : "444@qq.com",
"hobby" : "跑步、游泳、篮球"
}
}
]
}
}
1.3、range查询
range允许我们按照指定范围去查找,如查找age在[21,23]之间的数据
GET /user/_search
{
"query": {
"range": {
"age": {
"gte": 21,
"lte": 23
}
}
}
}
## 响应
{
"took" : 85,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 3,
"max_score" : 1.0,
"hits" : [
{
"_index" : "user",
"_type" : "people",
"_id" : "hWk5jHQBzgrkYgRNOrUU",
"_score" : 1.0,
"_source" : {
"name" : "李四",
"age" : 21,
"mail" : "222@qq.com",
"hobby" : "羽毛球、乒乓球、足球、篮球"
}
},
{
"_index" : "user",
"_type" : "people",
"_id" : "hmk5jHQBzgrkYgRNOrUU",
"_score" : 1.0,
"_source" : {
"name" : "王五",
"age" : 22,
"mail" : "333@qq.com",
"hobby" : "羽毛球、篮球、游泳、听音乐"
}
},
{
"_index" : "user",
"_type" : "people",
"_id" : "h2k5jHQBzgrkYgRNOrUU",
"_score" : 1.0,
"_source" : {
"name" : "赵六",
"age" : 23,
"mail" : "444@qq.com",
"hobby" : "跑步、游泳、篮球"
}
}
]
}
}
操作符包含以下
- gt 大于
- gte 大于等于
- lt 小于
- lte 小于等于
1.4、 match查询
match查询是一个标准查询,不管你需要全文本查询还是精确查询基本上都要用到它。
如果你使用match查询一个全文本字段,它会在真正查询之前用分析器先分析match一下查询字符。如果用match下指定了一个确切值,在遇到数字,日期,布尔值或者not_analyzed的字符串时,它将为你搜索你给定的值。
举例:查询爱好中包含篮球和音乐的数据
须知:下面的query 若没有operator,默认篮球与音乐是OR的关系
GET /user/_search
{
"query": {
"match": {
"hobby": {
"query": "篮球 音乐",
"operator": "and"
}
}
}
}
## 响应
{
"took" : 9,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.7382001,
"hits" : [
{
"_index" : "user",
"_type" : "people",
"_id" : "hmk5jHQBzgrkYgRNOrUU",
"_score" : 0.7382001,
"_source" : {
"name" : "王五",
"age" : 22,
"mail" : "333@qq.com",
"hobby" : "羽毛球、篮球、游泳、听音乐"
}
}
]
}
}
1.4.1、分页
分页涉及两个字段即from和size,from表示从哪条数据开始,size表示每页多少条数据。
from从0开始,默认返回10个结果。
获取靠后的数据,翻页成功较高
举例:分页查找(每页显示2条) 索引user中age大于20的数据
GET /user/_search
{
"query": {
"range": {
"age": {
"gte": 20
}
}
},
"from":0,
"size":2
}
## 响应
{
"took" : 41,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 5,
"max_score" : 1.0,
"hits" : [
{
"_index" : "user",
"_type" : "people",
"_id" : "hGk5jHQBzgrkYgRNOrUU",
"_score" : 1.0,
"_source" : {
"name" : "张三",
"age" : 20,
"mail" : "111@qq.com",
"hobby" : "羽毛球、乒乓球、足球"
}
},
{
"_index" : "user",
"_type" : "people",
"_id" : "hWk5jHQBzgrkYgRNOrUU",
"_score" : 1.0,
"_source" : {
"name" : "李四",
"age" : 21,
"mail" : "222@qq.com",
"hobby" : "羽毛球、乒乓球、足球、篮球"
}
}
]
}
}
1.4.2、排序
- 最好在数字类型或日期类型的字段上排序
- 对于多值类型或分词分析过的字段排序,系统会选一个值,我们无法得知该值
举例:分页查找(每页显示2条) 索引user中age大于20的数据 并安装age倒序
GET /user/_search
{
"query": {
"range": {
"age": {
"gte": 20
}
}
},
"from":0,
"size":2,
"sort": [
{
"age": {
"order": "desc"
}
}
]
}
## 响应
{
"took" : 57,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 5,
"max_score" : null,
"hits" : [
{
"_index" : "user",
"_type" : "people",
"_id" : "iGk5jHQBzgrkYgRNOrUU",
"_score" : null,
"_source" : {
"name" : "孙七",
"age" : 24,
"mail" : "555@qq.com",
"hobby" : "听音乐、看电影、羽毛球"
},
"sort" : [
24
]
},
{
"_index" : "user",
"_type" : "people",
"_id" : "h2k5jHQBzgrkYgRNOrUU",
"_score" : null,
"_source" : {
"name" : "赵六",
"age" : 23,
"mail" : "444@qq.com",
"hobby" : "跑步、游泳、篮球"
},
"sort" : [
23
]
}
]
}
}
1.4.3、_source 获取存储的原始数据
_source支持使用通配符,如_source[“name*”,“year”]。如果文档数据没有存储_source,那就只返回匹配文档的元数据
举例:取出索引user中id、name、hobby、abc字段
GET /user/_search
{
"query": {
"match_all": {}
},
"_source": ["age","name","hob*","abc"]
}
## 响应
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 5,
"max_score": 1,
"hits": [
{
"_index": "user",
"_type": "people",
"_id": "hGk5jHQBzgrkYgRNOrUU",
"_score": 1,
"_source": {
"name": "张三",
"age": 20,
"hobby": "羽毛球、乒乓球、足球"
}
},
{
"_index": "user",
"_type": "people",
"_id": "hWk5jHQBzgrkYgRNOrUU",
"_score": 1,
"_source": {
"name": "李四",
"age": 21,
"hobby": "羽毛球、乒乓球、足球、篮球"
}
},
{
"_index": "user",
"_type": "people",
"_id": "iGk5jHQBzgrkYgRNOrUU",
"_score": 1,
"_source": {
"name": "孙七",
"age": 24,
"hobby": "听音乐、看电影、羽毛球"
}
},
{
"_index": "user",
"_type": "people",
"_id": "hmk5jHQBzgrkYgRNOrUU",
"_score": 1,
"_source": {
"name": "王五",
"age": 22,
"hobby": "羽毛球、篮球、游泳、听音乐"
}
},
{
"_index": "user",
"_type": "people",
"_id": "h2k5jHQBzgrkYgRNOrUU",
"_score": 1,
"_source": {
"name": "赵六",
"age": 23,
"hobby": "跑步、游泳、篮球"
}
}
]
}
}
由于文档中不存在abc列,所以响应里并未展示该列
1.4.4、脚本字段
对源数据进行修饰并展示出去
举例:将索引user中age=20的数据中age字段添上"岁" 并输出
GET /user/_search
{
"query": {
"match": {
"age": "20"
}
},
"script_fields": {
"age": {
"script": {
"lang": "painless",
"source":"doc['age'].value+'岁'"
}
}
}
}
## 响应
{
"took" : 6,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "user",
"_type" : "people",
"_id" : "hGk5jHQBzgrkYgRNOrUU",
"_score" : 1.0,
"fields" : {
"age" : [
"20岁"
]
}
}
]
}
}
1.5、bool查询
bool查询是用来合并多个条件查询结果的布尔逻辑,它包含以下操作符:
- must 多个查询条件的完全匹配,相当于AND
- must_not 多个查询条件的相反匹配 相当于NOT
- should 其中的查询条件至少有一个会匹配,相当于OR
这些参数可以分别集成一个查询条件或多个查询条件的数据
举例:查询爱好中包含篮球,不包含音乐的,年龄是21~23之间的数据
GET /user/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"hobby": "篮球"
}
}
],
"must_not": [
{
"match": {
"hobby": "音乐"
}
}
],
"should": [
{
"terms": {
"age": [
"21",
"22",
"23"
]
}
}
]
}
}
}
## 响应
{
"took" : 46,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 1.287682,
"hits" : [
{
"_index" : "user",
"_type" : "people",
"_id" : "hWk5jHQBzgrkYgRNOrUU",
"_score" : 1.287682,
"_source" : {
"name" : "李四",
"age" : 21,
"mail" : "222@qq.com",
"hobby" : "羽毛球、乒乓球、足球、篮球"
}
},
{
"_index" : "user",
"_type" : "people",
"_id" : "h2k5jHQBzgrkYgRNOrUU",
"_score" : 1.2239686,
"_source" : {
"name" : "赵六",
"age" : 23,
"mail" : "444@qq.com",
"hobby" : "跑步、游泳、篮球"
}
}
]
}
}
1.5.1、过滤查询
查询年龄是21岁的用户数据
GET /user/_search
{
"query": {
"bool": {
"filter": {
"term": {
"age": "21"
}
}
}
}
}
## 响应
{
"took" : 29,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.0,
"hits" : [
{
"_index" : "user",
"_type" : "people",
"_id" : "hWk5jHQBzgrkYgRNOrUU",
"_score" : 0.0,
"_source" : {
"name" : "李四",
"age" : 21,
"mail" : "222@qq.com",
"hobby" : "羽毛球、乒乓球、足球、篮球"
}
}
]
}
}
1.6、短语搜索 Match Phrase
就像match
查询对于标准全文搜索是一种最常用的查询一样,当你想找到彼此邻近搜索词时,就会想到match_phrase
查询
举例:搜索 title包含"Beautiful Mind"的数据
语法示例如下:
GET /movies/_search
{
"query": {
"match_phrase": {
"title":"Beautiful Mind"
}
}
}
类似 match
查询, match_phrase
查询首先将查询字符串解析成一个词项列表,然后对这些词项进行搜索,但只保留那些包含 全部 搜索词项,且 位置 与搜索词项相同的文档,且中间不许夹杂其他词,即 Beautiful 在前,Mind在后,Mind紧挨Beautiful
有时候,搜索词不是紧挨着的,如果仍需要可以搜索匹配到,这就需要使用slop
了,slop
表示搜索词项相隔多远时 仍可匹配
举例:查询title包含"Beautiful Mind"的数据,搜索词项可相隔1个位置
GET /movies/_search
{
"query": {
"match_phrase": {
"title":{
"query": "Beautiful Mind",
"slop": 1
}
}
}
}
## 响应
{
"took" : 13,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.37229446,
"hits" : [
{
"_index" : "movies",
"_type" : "test",
"_id" : "1",
"_score" : 0.37229446,
"_source" : {
"title" : "Beautiful A,Mind"
}
}
]
}
}
1.7、Query String 查询
创建一个索引及数据来模拟此种查询
POST people/qry/1
{
"name":"ta jiushiwo",
"age":24
}
POST people/qry/2
{
"name":"wo jiushiwo",
"age":24
}
查询可以使用AND、OR
举例:查询 name中包含了"wo"或者"ta"的数据
GET people/_search
{
"query": {
"query_string": {
"default_field": "name",
"query": "wo OR ta"
}
}
}
## 响应
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "people",
"_type" : "qry",
"_id" : "2",
"_score" : 0.2876821,
"_source" : {
"name" : "wo jiushiwo",
"age" : 24
}
},
{
"_index" : "people",
"_type" : "qry",
"_id" : "1",
"_score" : 0.2876821,
"_source" : {
"name" : "ta jiushiwo",
"age" : 24
}
}
]
}
}
举例:查询 name中包含 “wo"或者"ta” 且 包含”jiushiwo“的数据
GET people/_search
{
"query": {
"query_string": {
"default_field": "name",
"query": "(wo OR ta) and jiushiwo"
}
}
}
## 响应
{
"took" : 15,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 0.5753642,
"hits" : [
{
"_index" : "people",
"_type" : "qry",
"_id" : "2",
"_score" : 0.5753642,
"_source" : {
"name" : "wo jiushiwo",
"age" : 24
}
},
{
"_index" : "people",
"_type" : "qry",
"_id" : "1",
"_score" : 0.5753642,
"_source" : {
"name" : "ta jiushiwo",
"age" : 24
}
}
]
}
}
1.8、Simple Query String 查询
- 类似Query String,但会忽略错误的语法,同时只支持部分查询语法
- 不支持AND/OR/NOT,会把这些当做字符串处理
- Term之间默认的关系是OR,可以指定Operator
以下符号可以替代AND/OR/NOT
- +替代 AND
- | 替代 OR
- - 替代 NOT
举例:查询索引user中name同时包含"wo"、"ta"的数据
GET people/_search
{
"query": {
"simple_query_string": {
"query": "wo +ta",
"fields": ["name"]
}
}
}
## 响应
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 0,
"max_score" : null,
"hits" : [ ]
}
}
举例:查询索引user中name包含"wo"或"ta"的数据
GET people/_search
{
"query": {
"simple_query_string": {
"query": "wo|ta",
"fields": ["name"]
}
}
}
## 响应
{
"took" : 11,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "people",
"_type" : "qry",
"_id" : "2",
"_score" : 0.2876821,
"_source" : {
"name" : "wo jiushiwo",
"age" : 24
}
},
{
"_index" : "people",
"_type" : "qry",
"_id" : "1",
"_score" : 0.2876821,
"_source" : {
"name" : "ta jiushiwo",
"age" : 24
}
}
]
}
}