Elasticsearch+Kibana·入门·贰·DSL专题

文章目录

  • 1 DSL查询文档
    • 1.1 DSL查询分类
    • 1.2.全文检索查询
      • 1.2.1 使用场景
      • 1.2.2.基本语法:match与multi_match
      • 1.2.3 示例:match与multi_match
    • 1.3.精准查询
      • 1.3.1 term查询
      • 1.3.2 range查询
    • 1.4 地理坐标查询
      • 1.4.1 矩形范围查询
      • 1.4.2 附近查询
    • 1.5.复合查询
      • 1.5.1 相关性算分
        • 1.5.1.2 算分函数查询
        • 1.5.1.3 算分函数运行流程
        • 1.5.1.4 算分函数示例
      • 1.5.2 布尔查询
        • 1.5.2.1 语法示例
        • 1.5.2.2 示例

1 DSL查询文档

1.1 DSL查询分类

查询类型 解释 关键字 相当于MySQL中
查询所有 查询出所有数据,一般测试用。 ① match_all select *
全文检索(full text)查询 利用分词器对用户输入内容分词,然后去倒排索引库中匹配。 ①match_query;② multi_match_query 模糊查询
精确查询 根据精确词条值查找数据,一般查找keyword、数值、日期、boolean等类型字段 ① ids;② range;③ term
地理(geo)查询 根据经纬度查询 ① geo_distance;② geo_bounding_box
复合(compound)查询 将上述各种查询条件组合起来,合并查询条件。 ① bool;② function_score

DSL语法:

GET /indexName/_search
{
  "query": {
    "查询类型": {
      "查询条件": "条件值"
    }
  }
}
// 查询所有
GET /indexName/_search
{
  "query": {
    "match_all": {
    }
  }
}

1.2.全文检索查询

1.2.1 使用场景

商城输入框
Elasticsearch+Kibana·入门·贰·DSL专题_第1张图片

1.2.2.基本语法:match与multi_match

属性 解释 备注
match 单字段查询 根据一个字段查询
multi_match 多字段查询,任意一个字段符合条件,只要查到就给你返回 根据多个字段查询,参与查询字段越多,查询性能越差,建议使用all字段,copy_to方法优化

match查询语法:

GET /indexName/_search
{
  "query": {
    "match": {
      "FIELD": "TEXT"
    }
  }
}

mulit_match语法:

GET /indexName/_search
{
  "query": {
    "multi_match": {
      "query": "TEXT",
      "fields": ["FIELD1", " FIELD12"]
    }
  }
}

1.2.3 示例:match与multi_match

multi_match 示例:
Elasticsearch+Kibana·入门·贰·DSL专题_第2张图片

match 示例:
Elasticsearch+Kibana·入门·贰·DSL专题_第3张图片

注意:我们发现上述match、multi_match查询到的结果相同,因为:在Elasticsearch+Kibana·入门·壹中创建索引库时,我们使用到组合字段all,已经将brand、name、business值利用copy_to复制到all字段中,因此会出现查询结果相同。

  • 在实际开发者,当查询多个字段时使用copy_to方法,可以减少搜索字段,相较可以提高查询性能。

1.3.精准查询

精准查询一般查找keyword、数值、日期类型字段,所以不会对搜索条件分词

属性 解释
term 根据词条精确值查询
range 根据值的范围查询

1.3.1 term查询

语法:

// term查询
GET /indexName/_search
{
  "query": {
    "term": {
      "FIELD": {
        "value": "VALUE"
      }
    }
  }
}

term查询:
Elasticsearch+Kibana·入门·贰·DSL专题_第4张图片

1.3.2 range查询

语法:

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

range查询示例:
Elasticsearch+Kibana·入门·贰·DSL专题_第5张图片

1.4 地理坐标查询

官方参阅文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-queries.html

应用场景:例如查找附近的酒店等。

1.4.1 矩形范围查询

Elasticsearch+Kibana·入门·贰·DSL专题_第6张图片

语法:

// geo_bounding_box查询
GET /indexName/_search
{
  "query": {
    "geo_bounding_box": {
      "FIELD": {
        "top_left": { // 左上点
          "lat": 31.1,
          "lon": 121.5
        },
        "bottom_right": { // 右下点
          "lat": 30.9,
          "lon": 121.7
        }
      }
    }
  }
}

1.4.2 附近查询

附近查询(距离查询)geo_distance:以指定点为中心,指定距离为半径的圆形区域内所需信息。
Elasticsearch+Kibana·入门·贰·DSL专题_第7张图片

语法:

// geo_distance 查询
GET /indexName/_search
{
  "query": {
    "geo_distance": {
      "distance": "15km", // 半径
      "FIELD": "31.21,121.5" // 圆心
    }
  }
}

附近查询示例:Elasticsearch+Kibana·入门·贰·DSL专题_第8张图片

1.5.复合查询

复合(compound)查询:将简单查询组合起来,实现复杂的搜索逻辑。

属性 解释
fuction score 算分函数查询,通过控制文档相关性算分(权重),控制文档排名
bool query 布尔查询,利用逻辑关系组合多个查询其他查询,实现复杂搜索

1.5.1 相关性算分

在elasticsearch中,早期使用的打分算法是TF-IDF算法,公式如下:
Elasticsearch+Kibana·入门·贰·DSL专题_第9张图片

注意:TF-IDF算法的缺陷,词条频率越高,文档得分(score)越高,词条出现次数对文档影响较大。而BM25则会使单个词条的算分出现上限,分子(词条出现次数过多)趋向于文档中词条总数时,曲线会变平滑,此时相关性算分幅度基本保持不变,使得控制文档排名业务复杂。
Elasticsearch+Kibana·入门·贰·DSL专题_第10张图片

5.1版本后,elasticsearch将算法改进为BM25算法,公式如下
Elasticsearch+Kibana·入门·贰·DSL专题_第11张图片

1.5.1.2 算分函数查询

算分函数内容 解释
原始查询 查询方式可根据需求改变,如:查询品牌中出现万怡字眼的,并中根据下方过滤,得到最终负荷调节的将要设置算分的文档,并得到默认原始算分文档
过滤条件 查询方式可根据需求改变,得到最终符合条件的将要设置算分文档
算分函数 与下方boost_mode相结合,再依据原始算分,得到最终算分结果
运算模式 也就是加权模式,multiply与weight相乘(默认方式)

1.5.1.3 算分函数运行流程

① 根据原始条件查询文档,得到原始算分
② 根据过滤条件,过滤文档
③ 得到符合过滤条件的文档,设置权重,得到函数算分
④ 将此处的加权模式上方函数算分做出计算,得到最终相关性算分

1.5.1.4 算分函数示例

#将上海地区的如家品牌酒店排名靠前
GET /hotel/_search
{
  "query": {
    "function_score":{
      "query": {
        "match": {
          "all": "上海"
        }
      },
      "functions": [
        {
          "filter": {
            "term": {
              "brand": "如家"
            }
          },
          "weight": 100
        }
      ],
      "boost_mode": "multiply"
    }
  }
}

1.5.2 布尔查询

布尔查询(bool):查询时,在bool方法体内,使用一个或多个支持下的组合,每一个字句就是一个子查询,子查询的组合方式:

条件 解释
must 必须匹配每个子查询,类似“与”
should 选择性匹配子查询,类似“或”
must_not 必须不匹配,不参与算分,类似“非”
filter 必须匹配,不参与算分

注意:打分的字段越多,查询的性能也越差。优化方法:

  • ①当全文检索时,使用must查询,参与算分
  • ②其他过滤条件,采用filter查询,不参与算分

1.5.2.1 语法示例

GET /hotel/_search
{
  "query": {
    "bool": {
      "must": [
        {"term": {"city": "上海" }}
      ],
      "should": [
        {"term": {"brand": "皇冠假日" }},
        {"term": {"brand": "华美达" }}
      ],
      "must_not": [
        { "range": { "price": { "lte": 500 } }}
      ],
      "filter": [
        { "range": {"score": { "gte": 45 } }}
      ]
    }
  }
}

1.5.2.2 示例

需求:搜索名字包含“如家”,价格不高于400,在坐标31.21,121.5周围10km范围内的酒店。

#搜索名字包含“如家”,价格不高于400,在坐标31.21,121.5周围10km范围内的酒店

GET /hotel/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {//模糊查询,匹配名字中含有如家关键字的酒店吗
            "name": "如家"
          }
        }
      ],
      "must_not": [
        {
          "range": {//子查询
             "price": {
              "gt": 400 //非大于400,即小于400的价格
            }
          }
        }
      ],
      "filter": [ //过滤子查询,得到位置信息内的相关酒店
        {
          "geo_distance": {
            "distance": "10km",
            "location": {
              "lat": 31.21,
              "lon": 121.5
            }
          }
        }
      ]
    }
  }
}

你可能感兴趣的:(ES,elasticsearch,大数据,搜索引擎)