主要内容:_search api的基本语法介绍。filter和query查询条件的区别
1、_search api的基础语法介绍
1.1 基础语法回顾
GET /_search
GET /ecommerce,company/_search
GET /_search
{
"from": 10,
"size": 20
}
1.2 Query DSL语法
## Query DSL的基本语法
{
QUERY_NAME: { ##
ARGUMENT: VALUE, ##
ARGUMENT: VALUE,...
}
}
{
QUERY_NAME: {
FIELD_NAME: { ##
ARGUMENT: VALUE,
ARGUMENT: VALUE,...
}
}
}
查询示例
GET /_search
{
"query": {
"match_all": {}
}
}
GET /ecommerce/_search
{
"query": {
"match": {
"name": "special"
}
}
}
1.3 组合多个搜索条件
构造的moke数据
POST website/_doc
{
"title": "my hadoop article",
"content": "hadoop is very bad",
"author_id": 111
}
POST website/_doc
{
"title": "my elasticsearch article",
"content": "es is very bad",
"author_id": 110
}
POST website/_doc
{
"title": "my elasticsearch article",
"content": "es is very goods",
"author_id": 111
}
搜索需求:title必须包含elasticsearch,content可以包含'elasticsearch'也可以不包含,author_id必须不为111
GET /website/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"title": "elasticsearch"
}
}
],
"should": [
{
"match": {
"content": "elasticsearch"
}
}
],
"must_not": [
{
"match": {
"author_id": 111
}
}
]
}
}
}
查询需求02:
name必须是tom 其他条件可以不满足
GET /test_index/_search
{
"query": {
"bool": {
"must": {
"match": {
"name": "tom"
}
},
"should": [
{
"match": {
"hired": true
}
},
{
"bool": {
"must": {
"match": {
"personality": "good"
}
},
"must_not": {
"match": {
"rude": true
}
}
}
}
],
"minimum_should_match": 1 ##至少匹配到一条
}
}
}
2、ES 的query 和 filter 区别
插入的示例数据
POST /company/_doc/1
{
"address": {
"country": "china",
"province": "guangdong",
"city": "guangzhou"
},
"name": "jack",
"age": 27,
"join_date": "2017-01-01"
}
POST /company/_doc/2
{
"address": {
"country": "china",
"province": "jiangsu",
"city": "nanjing"
},
"name": "tom",
"age": 30,
"join_date": "2016-01-01"
}
POST /company/_doc/3
{
"address": {
"country": "china",
"province": "shanxi",
"city": "xian"
},
"name": "marry",
"age": 35,
"join_date": "2015-01-01"
}
搜索请求,年龄必须大于等于30,同时join_date必须是2016年1月1号
GET /company/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"join_date": "2016-01-01"
}
}
],
"filter": {
"range": {
"age": {
"gte": 30
}
}
}
}
}
}
2.1、query DSL
在查询上下文中,查询会回答这个问题——“这个文档匹不匹配这个查询,它的相关度高么?”
如何验证匹配很好理解,如何计算相关度呢?ES中索引的数据都会存储一个_score分值,分值越高就代表越匹配。另外关于某个搜索的分值计算还是很复杂的,因此也需要一定的时间。
查询上下文 是在 使用query进行查询时的执行环境,比如使用search的时候。还有需要按照相关度进行排序的时候。
一些query的场景:
与full text search的匹配度最高
包含run单词,如果包含这些单词:runs、running、jog、sprint,也被视为包含run单词
包含quick、brown、fox。这些词越接近,这份文档的相关性就越高
2.2、filter DSL
在过滤器上下文中,查询会回答这个问题——“这个文档匹不匹配?”
答案很简单,是或者不是。它不会去计算任何分值,也不会关心返回的排序问题,因此效率会高一点。
过滤上下文 是在使用filter参数时候的执行环境,比如在bool查询中使用Must_not或者filter
一些filter的情况:
创建日期是否在2013-2014年间?
status字段是否为published?
lat_lon字段是否在某个坐标的10公里范围内?
概述总结:
filter和query的选择:
一般来说,如果你是在进行搜索,需要将最匹配搜索条件的数据先返回,那么用query;如果你只是要根据一些条件筛选出一部分数据,不关注其排序,那么用filter
除非是你的这些搜索条件,你希望越符合这些搜索条件的document越排在前面返回,那么这些搜索条件要放在query中;如果你不希望一些搜索条件来影响你的document排序,那么就放在filter中即可
filter与query的性能:
filter,不需要计算相关度分数,不需要按照相关度分数进行排序,同时还有内置的自动cache最常使用filter的数据
query,相反,要计算相关度分数,按照分数进行排序,而且无法cache结果
2.3、filter和query合并
比如说我们有这样一条查询语句,获取邮件内容中带“business opportunity” 的:
{
"match": {
"email": "business opportunity"
}
}
然后我们想要让这条语句加入 term 过滤,只在收信箱中匹配邮件:
{
"term": {
"folder": "inbox"
}
}
search API中只能包含 query 语句,所以我们需要用 filtered 来同时包含 "query" 和 "filter" 子句:
{
"filtered": {
"query": { "match": { "email": "business opportunity" }},
"filter": { "term": { "folder": "inbox" }}
}
}
我们在外层再加入 query 的上下文关系:
GET /_search
{
"query": {
"filtered": {
"query": { "match": { "email": "business opportunity" }},
"filter": { "term": { "folder": "inbox" }}
}
}
}
参考内容:
ES 的query 和 filter 区别Java王文健的Blogs~~!-CSDN博客 https://blog.csdn.net/qq_29580525/article/details/80908523