ElasticSearch 的DSL查询文档、RestClient查询、旅游案例

一、DSL查询文档

本章目标

  • 文本检索:match_all、match、multi_match
  • 精确查询:term、range
  • 地理坐标查询:geo_distance
  • 复合查询:function_score、bool

1. 说明

查询语法:

GET /索引库名/_search
{
  "query": {},     #放查询条件
  "sort": [],      #放排序条件
  "from": 起始索引, #放分页的起始索引
  "size": 查询数量, #放分页的查询几条
  "highlight": {}, #放高亮字段
  "aggs": {},      #放聚合分组条件
  "suggest": {}    #放搜索提示条件
}

1.1 查询功能分类

Elasticsearch提供了基于JSON的DSL(Domain Specific Language)来定义查询。常见的查询类型包括:

  • 查询所有:查询出所有数据,一般测试用。例如:match_all

  • 全文本检索(full text)查询:利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如:

    • match

    • multi_match

  • 精确查询:根据精确词条值查找数据,一般是查找keyword、数值、日期、boolean等类型字段。例如:

    • range

    • term

  • 地理(geo)查询根据经纬度查询。例如:

    • geo_distance

    • geo_bounding_box

  • 复合(compound)查询复合查询可以将上述各种查询条件组合起来,合并查询条件。例如:

    • bool

    • function_score

1.2 查询语法说明

查询的语法基本一致:

GET /索引名称/_search
{
  "query": {
    "查询类型": {
      "查询条件": "条件值"
    }
  }
}

我们以查询所有为例,其中:

  • 查询类型为match_all

  • 没有查询条件

# 查询所有
GET /索引名称/_search
{
  "query": {
    "match_all": {
    }
  }
}

其它查询无非就是查询类型查询条件的变化

2. 文本检索

全文检索查询的基本流程如下:

  • 对用户搜索的内容做分词,得到词条

  • 根据词条去倒排索引库中匹配,得到文档id

  • 根据文档id找到文档,返回给用户

比较常用的场景包括:

  • 商城的输入框搜索

  • 百度输入框搜索

例如京东:

因为是拿着词条去匹配,因此参与搜索的字段也必须是可分词的text类型的字段。

语法

常见的全文检索查询包括:

  • match查询:单字段查询

  • multi_match查询:多字段查询,任意一个字段符合条件就算符合查询条件。注意:字段越多,性能越差

match

match查询语法如下:

GET /索引名称/_search
{
  "query": {
    "match": {
      "字段": "搜索值"
    }
  }
}

mulit_match

mulit_match语法如下:

GET /索引名称/_search
{
  "query": {
    "multi_match": {
      "query": "搜索值",
      "fields": ["字段1", "字段2", ...]
    }
  }
}

示例

#match 单字段检索
GET /hotel/_search
{
  "query": {
    "match": {
      "all": "北京如家"
    }
  }
}

#multi_match多字段检查
GET /hotel/_search
{
  "query": {
    "multi_match": {
      "query": "北京如家",
      "fields": ["name", "brand", "business"]
    }
  }
}

注意

多字段检索的性能问题:使用多字段检索时,字段越多,检索的性能越差

解决方案:使用copy_to,把多个字段值拷贝到一个字段里,对这个字段用match检索,可以达到同样效果,而且效率更高

3. 精确查询

精确查询一般是查找keyword、数值、日期、boolean等类型字段。所以不会对搜索条件分词。常见的有:

  • term:根据词条精确值查询

    因为精确查询是不分词的,所有查询的条件也必须是不分词的词条。查询时,用户输入的内容跟自动值完全匹配时才认为符合条件。如果用户输入的内容过多反而搜索不到数据

  • range:根据值的范围查询

    范围查询,一般应用在对数值类型做范围过滤的时候。比如做价格范围过滤。

语法

term查询

# term查询
GET /indexName/_search
{
  "query": {
    "term": {
      "字段": {
        "value": "值"
      }
    }
  }
}

range查询

# range查询
GET /indexName/_search
{
  "query": {
    "range": {
      "字段": {
        "gte": 10, # 这里的gte代表大于等于,gt则代表大于
        "lte": 20 # lte代表小于等于,lt则代表小于
      }
    }
  }
}

示例

#   1. term词条匹配。不分词,必须精确匹配。 查询“如家”品牌的酒店
GET /hotel/_search
{
  "query": {
    "term": {
      "brand": {
        "value": "如家"
      }
    }
  }
}

#   2. range范围匹配。查询price价格在300~500之间的酒店
GET /hotel/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 300,
        "lte": 500
      }
    }
  }
}

4. 地理坐标查询

所谓的地理坐标查询,其实就是根据经纬度查询,官方文档:Geo queries | Elasticsearch Guide [8.7] | Elastic

常见的使用场景包括:

  • 携程:搜索我附近的酒店

  • 滴滴:搜索我附近的出租车

  • 微信:搜索我附近的人

附近的酒店:

附近的车:

语法

矩形范围查询【了解】

矩形范围查询,也就是geo_bounding_

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值