请求参数的查询(QueryString)
查询[字段]包含[内容]的文档
GET请求 http://192.168.1.181:9200/shop/_doc/_search?q=desc:我真帅
GET请求 http://192.168.1.181:9200/shop/_doc/_search?q=desc:我真帅&q=age:18
这种方式一般称之为QueryString查询方式,参数都是在URL中作为请求参数的。
点击一下,咻的一下就可以查看官方文档了,可直接翻译es DSL操作官方文档
DSL基本语法
QueryString用的很少,一旦参数复杂就很难构建,所以大多数查询都是使用dsl来进行查询比较好。
- Domain Specific Language
- 特定领域语言
- 基于JSON格式的数据查询
- 查询更灵活,有利于复杂查询
1、match语法
#查询
POST http://192.168.1.181:9200/shop/_doc/_search
{
"query":{
"match":{
"desc":"我真帅"
}
}
}
# 同等于: GET http://192.168.1.181:9200/shop/_doc/_search?q=desc:我真帅
#判断某个字段是否存在
{
"query":{
"exists":{
"field":"desc"
}
}
}
!补充:语法格式为一个json object,内容都是key-value键值对,json可以嵌套。 key可以是一些es的关键字,也可以是某个field字段
2、match_all
在索引中查询所有的文档
GET http://113.98.58.50:9200/shop/_doc/_search
POST http://113.98.58.50:9200/shop/_doc/_search
{
"query":{
"match_all":{}
},
"_source":["id","nickname","age"], # 类似mysql中select * 替换
"from": 0, # 从那一条数据开始
"size": 10 # 每一页展示多少条数据
}
3、match_phrase
match:分词后只要有数据就会进行匹配然后返回
match_phrase:分词结果必须在text字段分词中都包含,而且顺序必须相同,而且必须都是连续的(搜索相对而言比较严格)
# slop:允许词语间跳过的数量
POST http://113.98.58.50:9200/shop/_doc/_search
{
"query": {
"match_phrase": {
"desc": {
"query": "大学 毕业 研究生",
"slop": 2
}
}
}
}
4、match 扩展
operator:
- or:搜索内容分词后,只要存在一个词语匹配就能有结果
- and:搜索内容分词后,都要满足词语匹配
POST http://113.98.58.50:9200/shop/_doc/_search
{
"query": {
"match": {
"desc": "我真帅!"
}
}
}
# 等同于
{
"query": {
"match": {
"desc": {
"query": "xbox游戏机",
"operator": "or"
}
}
}
}
# 相当于 select * from shop where desc='xbox' or|and desc='游戏机'
- minimum_should_match:最低匹配精度,至少有[分词后的词语个数]百分位,的出一个数据值取整。举个🌰:当前属性设置为70,若一个用户查询检索内容分词后有10个词语,那么匹配度就是1070%=7,则desc中至少需要有7个成语进行匹配,就展示。若分词后有八个,则8*70% =5.6,则desc中至少需要有5个成语匹配,就展示。
- minimum_shodld_match 也能设置具体的数字,表示个数
POST http://113.98.58.50:9200/shop/_doc/_search
{
"query": {
"match": {
"desc": {
"query": "女友在我生日的时候送了我一双限量版球鞋,可把我开心坏了。",
"minimum_should_match": "60%"
}
}
}
}
根据文档主键ids搜索
#查询当个
GET /shop/_doc/1001
#查询多个
POST http://113.98.58.50:9200/shop/_doc/_search
{
"query": {
"ids": {
"type": "_doc",
"values": ["1001", "1010", "1008"]
}
}
}
5、multi_match/boost
#满足使用match在多个字段中进行查询的需求
POST http://113.98.58.50:9200/shop/_doc/_search
{
"query": {
"multi_match": {
"query": "王二 18",
"fields": ["name", "age"]
}
}
}
#boost
#权重,为某个字段设置权重,权重越高,文档相关性得分就越高。通畅来说搜索商品名称要比商品简介的权重更高。
{
"query": {
"multi_match": {
"query": "王二 18",
"fields": ["name", "age^10"]
}
}
}
#age^10 代表搜索提升10倍相关性,也就是说用户搜索的时候其实以这个age为主,name为辅,age的匹配相关度当然要提高权重比例了。
6、term
搜索的时候会吧用户搜索内容,比如:"你是真的丑爆了!"作为一个整体的关键字去搜索,而不会对其他的分词后在搜索。
POST http://113.98.58.50:9200/shop/_doc/_search
{
"query":{
"term":{
"desc":"你是真的丑爆了!"
}
}
}
# 可以对比:
{
"query": {
"match": {
"desc": "你是真的丑爆了!"
}
}
}
# terms 多个词语匹配检索
# 相当于是tag标签查询,比如慕课网的一些淘宝会打上衣服、裤子、鞋子、袜子这样的标签,可以完全匹配做类似标签的查询
{
"query":{
"terms":{
"desc":["衣服","裤子","鞋子"]
}
}
}
!注:match会对"你是真的丑爆了!"些进行分词(其实就是全文搜索),在查询,而term则不会,直接吧"你是真的丑爆了!"作为一个整的词汇去搜索。
6、布尔查询
可以组合多重查询
- must:查询必须匹配搜索条件,比如and
- should: 查询匹配满足1个以上条件,比如or
- must_not:不匹配搜索条件,一个都不需要满足
POST http://113.98.58.50:9200/shop/_doc/_search
实操1:
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "我可真帅",
"fields": ["desc", "nickname"]
}
},
{
"term": {
"sex": 1
}
},
{
"term": {
"birthday": "1996-01-14"
}
}
]
}
}
}
{
"query": {
"bool": {
"should(must_not)": [
{
"multi_match": {
"query": "学习",
"fields": ["desc", "nickname"]
}
},
{
"match": {
"desc": "游戏"
}
},
{
"term": {
"sex": 0
}
}
]
}
}
}
实操2:
{
"query": {
"bool": {
"must": [
{
"match": {
"desc": "爱"
}
},
{
"match": {
"nickname": "爱"
}
}
],
"should": [
{
"match": {
"sex": "0"
}
}
],
"must_not": [
{
"term": {
"birthday": "1998-12-24"
}
}
]
}
}
}
#为指定词语加权
#特殊场景下,某些词语可以单独加权,这样可以排得更加靠前。
{
"query": {
"bool": {
"should": [
{
"match": {
"desc": {
"query": "律师",
"boost": 18
}
}
},
{
"match": {
"desc": {
"query": "进修",
"boost": 2
}
}
}
]
}
}
}
7、过滤器
对搜索出来的结果进行数据过滤。不会到es库里去搜,不会去计算文档的相关度分数,所以过滤的性能会比较高,过滤器可以和全文搜索结合在一起使用。
post_filter元素是一个顶层元素,只会对搜索结果进行过滤。不会计算数据的匹配度相关性分数,不会根据分数去排序,query则相反,会计算分数,也会按照分数去排序。
使用场景:
- query:根据用户搜索条件检索匹配记录
- post_filter:用于查询后,对结果数据的筛选
实操:查询账户金额大于80元,小于160元的用户。并且生日在1998-07-14的用户
- gte:大于等于
- lte:小于等于
- gt:大于
-
lt:小于
(除此以外还能做其他的match等操作也行)
POST http://113.98.58.50:9200/shop/_doc/_search
{
"query": {
"match": {
"desc": "玩吃鸡滴滴我呀!我钢枪贼6"
}
},
"post_filter": {
"range": {
"money": {
"gt": 60,
"lt": 1000
}
}
}
}
8、排序
es的排序同sql,可以desc也可以asc。也支持组合排序。
实操:
POST http://113.98.58.50:9200/shop/_doc/_search
{
"query": {
"match": {
"desc": "玩吃鸡滴滴我呀!我钢枪贼6"
}
},
"post_filter": {
"range": {
"money": {
"gt": 55.8,
"lte": 155.8
}
}
},
"sort": [
{
"age": "desc"
},
{
"money": "desc"
}
]
}
对文本排序
由于文本会被分词,所以往往要去做排序会报错,通常我们可以为这个字段增加额外的一个附属属性,类型为keyword,用于做排序。
- 创建新的索引
POST /shop2/_mapping
{
"properties": {
"id": {
"type": "long"
},
"nickname": {
"type": "text",
"analyzer": "ik_max_word",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
- 插入数据
POST /shop2/_doc
{
"id": 1001,
"nickname": "美丽的风景"
}
{
"id": 1002,
"nickname": "漂亮的小哥哥"
}
{
"id": 1003,
"nickname": "飞翔的巨鹰"
}
{
"id": 1004,
"nickname": "完美的天空"
}
{
"id": 1005,
"nickname": "广阔的海域"
}
- 排序
{
"sort": [
{
"nickname.keyword": "desc"
}
]
}
9、高亮highlight
高亮显示
POST http://113.98.58.50:9200/shop/_doc/_search
{
"query": {
"match": {
"desc": "你真帅"
}
},
"highlight": {
"pre_tags": ["<tag>"],
"post_tags": ["</tag>"],
"fields": {
"desc": {}
}
}
}