elasticsearch中DSL搜索

入门语法

请求参数的查询(QueryString)

查询[字段]包含[内容]的文档

GET /{index}/_doc/_search?q=desc:张三 
GET /{index}/_doc/_search?q=nickname:张&q=age:25

text与keyword搜索对比测试(keyword不会被倒排索引,不会被分词)
这种方式称之为QueryString查询方式,参数都是放在url中作为请求参数的。

DSL基本语法

QueryString用的很少,一旦参数复杂就难以构建,所以大多查询都会使用dsl来进行查询更好。

  • Domain Specific Language
  • 特定领域语言
  • 基于JSON格式的数据查询
  • 查询更灵活,有利于复杂查询
  • 语法格式为一个json object,内容都是key-value键值对,json可以嵌套。
  • key可以是一些es的关键字,也可以是某个field字段
    DSL格式语法:

查询

POST /{index}/_doc/_search 
{ 
	"query": { 
		"match": { 
			"desc": "CSND" 
		} 
	} 
}
## 查询 

判断某个字段是否存在

{ 
	"query": { 
		"exists": { 
			"field": "desc" 
		} 
	} 
}

查询所有数据并指定字段

# select id,naickname,age from table
{ 
	"query": { 
		"match_all": {} 
	},
	"_source": [
		"id", 
		"nickname", 
		"age"
	] 
}

分页查询

{ 
	"query": { 
		"match_all": {} 
	},
	# 从第几条开始
	"from": 0,
	# 每页显示多少 
	"size": 10 
}

深度分页

深度分页其实就是搜索的深浅度,比如第1页,第2页,第10页,第20页,是比较浅的;第10000页,第20000页就是很深了。
我们在获取第9999条到10009条数据的时候,其实每个分片都会拿到10009条数据,然后集合在一起,总共是10009*3=30027条数据,针对30027数据再次做排序,会获取最后10条数据。
如此一来,搜索得太深,就会造成性能问题,会耗费内存和占用cpu。而且es为了性能,他不支持超过一万条数据以上的分页查询。
如何解决深度分页带来的问题:应该避免深度分页操作(限制分页页数),比如最多只能提供100页的展示,从第101页开始就没了,毕竟用户也不会搜的那么深,我们平时搜索淘宝也就看个10来页就顶多了。
在这里插入图片描述

  • es默认限制10000条数据
# 提升搜索量 通过设置index.max_result_window来突破10000数据
PUT /shop/_settings 
{ 
	"index.max_result_window": "20000" 
}

搜索词不分词term

# 搜索词不分词term,直接精确搜索
# 搜索的时候会把用户搜索内容作为一整个关键词去搜索,而不会对其进行分词后再搜索
# match会对字段先进行分词(其实就是全文检索),在查询,而term则不会,直接把字段作为一个整的词汇去搜索。
{ 
	"query": { 
		"term": { 
			"desc": "慕课网" 
		} 
	} 
}

terms多个词语匹配检索

# 相当于是tag标签查询,比如博客的一些文章会打上spring、java这样的标签,可以完全匹配做类似标签的查询
{ 
	"query": { 
		"terms": { 
			"desc": [
				"spring", 
				"java", 
				"c"
			] 
		} 
	} 
}

match_phrase 短语匹配

# match:分词后只要有匹配就返回,match_phrase:分词结果必须在text字段分词中都包含,而且顺序必须相同,而且必须都是连续的。(搜索比较严格)
# slop 中间允许跳过的词数量
{ 
	"query": { 
		"match_phrase": { 
			"desc": { 
				"query": "大学 毕业 研究生", 
				"slop": 2 
			} 
		} 
	} 
}

match(operator)

# or:搜索内容分词后,只要存在一个词语匹配就展示结果
# and:搜索内容分词后,都要满足词语匹配
{ 
	"query": { 
		"match": { 
			"desc": { 
				"query": "xbox游戏机", 
				"operator": "or" 
			} 
		} 
	} 
}

minimum_should_match: 最低匹配精度

# 至少有[分词后的词语个数]x百分百,得出一个数据值取整。
# 举个例子:当前属性设置为 70 ,若一个用户查询检有10个词语,那么匹配度按照 10x70%=7,则desc中至少需要有7个词语匹配,就展示
# minimum_should_match 也能设置具体的数字,表示个数
{ 
	"query": { 
		"match": { 
			"desc": {
				 "query": "女友生日送我好玩的xbox游戏机",
				 "minimum_should_match": "60%" 
			 } 
		 } 
	 } 
 }

根据文档主键ids搜索

{ 
	"query": { 
		"ids": { 
			"type": "_doc",
			"values": [
				"1001","1002"
			]
		 } 
	 } 
 }

multi_match 满足使用match在多个字段中进行查询的需求

{ 
	"query": { 
		"multi_match": { 
			"query": "张三学习", 
			"fields": ["desc", "nickname"] 
		} 
	} 
}

boost 权重

# 为某个字段设置权重,权重越高,文档相关性得分就越高。通畅来说搜索商品名称要比商品简介的权重更高。
# nickname^10 代表搜索提升10倍相关性,也就是说用户搜索的时候其实以这个nickname为主,desc为辅,nickname的匹配相关度当然要提高权重比例了。
{ 
	"query": { 
		"multi_match": { 
			"query": "张三学习", 
			"fields": ["desc", "nickname^10"] 
		} 
	} 
}

布尔查询

可以组合多重查询

  • must:查询必须匹配搜索条件,譬如 and
  • should:查询匹配满足1个以上条件,譬如 or
  • must_not:不匹配搜索条件,一个都不要满足
{ 
	"query": { 
		"bool": { 
			"must": [],
			"should": [],
			"must_not": []
		} 
	} 
}

过滤器

对搜索出来的结果进行数据过滤。不会到es库里去搜,不会去计算文档的相关度分数,所以过滤的性能会比较高,过滤器可以和全文搜索结合在一起使用。

  • query:根据用户搜索条件检索匹配记录
  • post_filter:用于查询后,对结果数据的筛选
  • gte:大于等于
  • lte:小于等于
  • gt:大于
  • lt:小于
    (除此以外还能做其他的match等操作也行)
{ 
	"query": {
		"match": {
			"desc": "游戏" 
		} 
	},
	"post_filter": { 
		"range": {
			"money": {
				"gt": 60, 
				"lt": 1000 
			} 
		} 
	} 
}

排序

  • es的排序同sql,可以desc也可以asc。也支持组合排序。
  • 对文本排序
    由于文本会被分词,所以往往要去做排序会报错,通常我们可以为这个字段增加额外的一个附属属性,类型为keyword,用于做排序。
{ 
	"query": {
		"match": {
			"desc": "游戏" 
		} 
	},
	"sort": [ 
		{ 
			"age": "desc" 
		},
		{ 
			"money": "desc" 
		}
	] 
}

高亮highlight

{ 
	"query": { 
		"match": { 
			"desc": "慕课网" 
		} 
	},
	"highlight": { 
		# 自定义标签
		"pre_tags": ["<span>"], 
		# 自定义标签
		"post_tags": ["</span>"], 
		"fields": { 
			"desc": {} 
		} 
	} 
}

prefix根据前缀去查询

fuzzy模糊搜索

模糊搜索,并不是指的sql的模糊搜索,而是用户在进行搜索的时候的打字错误现象,搜索引擎会自动纠正,然后尝试匹配索引库中的数据。

wildcard占位符查询

  • ?:1个字符
  • *:1个或多个字符

scroll 游标查询

一次性查询1万+数据,往往会造成性能影响,因为数据量太多了。这个时候可以使用滚动搜索,也就是 scroll 。
滚动搜索可以先查询出一些数据,然后再紧接着依次往下查询。在第一次查询的时候会有一个滚动id,相当于一个 锚标记 ,随后再次滚动搜索会需要上一次搜索,根据这个进行下一次的搜索请求。每次搜索都是基于一个历史的数据快照,查询数据的期间,如果有数据变更,那么和搜索是没有关系的,搜索的内容还是快照。
官方文档:https://www.elastic.co/guide/cn/elasticsearch/guide/current/scroll.html

# scroll=1m,相当于是一个session会话时间,搜索保持的上下文时间为1分钟。
POST /shop/_search?scroll=1m 
{ 
	"query": { 
		"match_all": { } 
	},
	"sort" : ["_doc"], 
	"size": 5 
}
POST /_search/scroll 
{ 
	"scroll": "1m", 
	"scroll_id" : "你最后的scroll_id" 
}

mget批量查询

查询几个id就会返回几个数据,没有的数据也会返回,只不过found=false

  • found:true查询出来了数据,false无数据
POST /{index}/_doc/_search
{
	"ids" : ["1001","1003","10011"]
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赛赛liangks

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值