Skip to content

进阶检索 (一)

1、官方文档

https://www.elastic.co/guide/en/elasticsearch/reference/7.4/index.html** ** SearchAPI ::: theorem ES 支持两种基本方式检索:

  • 一个是通过使用 REST request URL 发送搜索参数(uri+检索参数)
  • 另一个是通过使用 REST request body 来发送它们(uri + 请求体) :::

2、检索信息

1)、切检索从_search开始

2)、uri+请求体进行检索

3、Query DSL

1)、基本语法格式

Elasticsearch 提供了一个可以执行查询的Json风格的DSL(domain-specific language 领域特定语言)。这个被称为 Query DSL 。该查询语言非常全面,并且刚开始的时候感觉有点复杂,真正学好它的方法是从一些基础的示例开始的。

  • 一个查询语句 的典型结构
json
{
  QUERY_NAME:{
     ARGUMENT: VALUE,
     ARGUMENT:VALUE,.....
 }
}
  • 如果是针对某个字段,那么它的结构如下:
json
{
  QUERY_NAME:{
      FIELD_NAME:{
        AGRUMENT: VALUE,
        AGRUMENT: VALUE,.......
    }   
  }
}
json
GET /bank/_search
{
  "query": {
    "match_all": {}
    
  },
  "from": 0,
  "size": 5, 
  "sort": [
    {
      "balance": {
        "order": "desc"
      }
    }
  ]
}
  • query 定义如何查询
  • matcha_all 查询类型【代表查询所有的所有】,es 中可以在query中组合非常多的查询类型完成复杂查询
  • 除了query参数之外,我们也可以传递其它的参数以改变查询结果。如sort,size
  • from+size 限定,完成分页功能
  • sort排序,多字段排序,会在前序字段相等时后续字段内部排序,否则以前序为准

2)、返回部分字段

json
GET /bank/_search
{
  "query": {
    "match_all": {}
    
  },
  "from": 0,
  "size": 5, 
  "sort": [
    {
      "balance": {
        "order": "desc"
      }
    }
  ],
  "_source": ["balance","firstname"]
}

3)、match 【匹配查询】

a、基本类型(非字符串),精确匹配

json
GET bank/_search
{
    "query": {
     "match": {
       "account_number": 20
     }
    
  }
}

match 返回 account_number = 20 的

b、字符串,全文检索

json
GET bank/_search
{
    "query": {
     "match": {
       "address": "mill road"
     }
    
  }
}

最终查出address中包含mill 或者 road 或者 mill road 的所有记录,并给出相关性得分。全文检索按照评分进行排序,会对检索条件进行分词匹配。

json
GET bank/_search
{
    "query": {
     "match": {
       "address.keyword": "694 Jefferson"
     }
    
  }
}

加了 .keyword 变成精确匹配 意思是 address = 694 Jefferson 才能被匹配出来,和下面match_phrase 的区别是 match_phrase 是短句匹配 address 中只要有 694 Jefferson 就能被查出来

4)、match_phrase 【短句查询】

将需要匹配的值当成一个整体单词(不分词)进行检索

json
GET bank/_search
{
    "query": {
     "match_phrase": {
       "address": "mill road"
     }
    
  }
}

查出address中包含mill road的所有记录,并给出相关性得分,注意 和 match 的区别 match 是分词匹配 意思是mill road 当成2个词去查,match_phrase 短句匹配 意思是mill road 合并为一个词查

5)、match_match 【多字段匹配】

json
GET bank/_search
{
    "query": {
     "multi_match": {
       "query": "mill movico",
       "fields": ["state","address"]
       
     }
  }
}

state 或者 address 包含 mill 或者 movico(注意 这里是分词查询!!!!)

6)、bool 【复合查询】

bool 用来做复合查询: 复合语句可以合并 任何 其它查询语句,包括复合语句,了解这一点是很重要的。这就意味着,复合语句之间可以互相嵌套,可以表达非常复杂的逻辑。

json
GET bank/_search
{
    "query": {
      "bool": {
        "must": [
          {"match": {
            "gender": "M"
           }
          },
           {"match": {
            "address": "mill"
           }
          }
        ],
        "must_not": [
          {"match": {
            "age": "28"
          }}
        ]
        ,"should": [
          {"match": {
            "lastname": "Wallace"
          }}
        ]
      }
    
  }
}

must 一定匹配 gender 一定是 M 的 must_not 一定不匹配 age 不等于 28 should 应该匹配 lastname 等于 Wallance 不等于也没有关系 也可以查出来

7)、filter 【结果过滤】

并不是所有的查询都需要产生分数,特别是那些仅用于“filteing” (过滤)的文档。为了不计算分数Elasticsearch会自动检查场景并且优化查询的执行。

json
GET bank/_search
{
    "query": {
      "bool": {
        "must": [
          {"match": {
            "gender": "M"
           }
          },
           {"match": {
            "address": "mill"
           }
          }
        ],
        "must_not": [
          {"match": {
            "age": "28"
          }}
        ]
        ,"should": [
          {"match": {
            "lastname": "Wallace"
          }}
        ],  
        "filter": {
          "range": {
            "age": {
              "gte": 10,
              "lte": 50
            }
          }
        }
      }
    
  }
}

filter不会计算相关性得分 只会对上一些条件查出的结果进行过滤,类似于JAVA stream 流 的 filter

8)、term

和match一样。匹配某个属性的值,全文检索字段用match,其他非text字段匹配term

json
GET bank/_search
{
  "query": {
    "term": {
      "age": "28"
    } 
  }
}

9)、aggregations(执行聚合)

聚合提供了从数据中分组和提取数据的能力。最简单的聚合方法大致等于SQL GROUP BY SQL 聚合函数。在Elasticsearch中,您有执行搜索返回hits(命中结果)分隔开的能力。这是非常强大且有效的,您可以执行查询和多个聚合,并且在一次使用中得到各自的(任何一个的)返回结果,使用一次简洁和简化的API来避免网络往返。

a、搜索address 中包含 mill的所有人的年龄分布以及平均年龄,但不显示这些人的详情。

json
GET bank/_search
{
    "query": {
     "match": {
       "address": "mill"
     }
    
  },
  "aggs": {
    "ageAgg": {
      "terms": {
        "field": "age",
        "size": 10
      }
    },
    "ageAvg":{"avg": {
      "field": "age"
    }},
    "balanceAvg":{
      "avg": {
        "field": "balance"
      }
    }
  },
  "size": 0
}

ageAgg 查询年龄分布情况即 年龄为 30的有多少人ageAvg 求age的平均值balanceAvg 求balance的平均值size = 0 返回值不返回查询的结果只返回聚合 aggregations 的结果

b、进阶 按照年龄聚合,并且请求这些年龄段的这些人的平均薪资。

json
GET bank/_search
{
  "query": {
    "match_all": {}
  }
  , "aggs": {
    "ageAgg": {
      "terms": {
        "field": "age",
        "size": 100
      },
      "aggs": {
        "ageAvg": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}

先按照年龄聚合,在求这些年龄段的平均薪资。

c、查出所有年龄分布,并且这些年龄段中M的平均薪资和F的平均薪资以及这个年龄段的总体平均薪资。

json
GET bank/_search
{
  "query": {
    "match_all": {}
  }
  , "aggs": {
    "ageAgg": {
      "terms": {
        "field": "age",
        "size": 100
      },
      "aggs": {
        "genderAgg": {
          "terms": {
            "field": "gender.keyword",
            "size": 10
          },
        "aggs": {
          "balanceAvg":{
            "avg": {
            "field": "balance"
          }
          }
        }
        },
        "ageBananceAvg":{
          "avg": {
            "field": "balance"
          }

        }
      }
    }
  }
}