ElasticSearch 查询实践(中)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: ElasticSearch 查询实践

二.DSL语言高级查询

1.Query DSL概述


**Domain Specific Language **


领域专用语言


Elasticsearch provides a ful1 Query DSL based on JSON to define queries

Elasticsearch提供了基于JSON的DSL来定义查询。


DSL由叶子查询子句和复合查询子句两种子句组成。


image.png


2.无查询条件


无查询条件是查询所有,默认是查询所有的,或者使用match_all表示所有


GET /es_db/_doc/_search 
{ 
"query":{ 
"match_all":{} 
} 
} 


返回结果


#! Deprecation: [types removal] Specifying types in search requests is deprecated.
{
  "took" : 12,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 5,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "es_db",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "张三",
          "sex" : 1,
          "age" : 25,
          "address" : "广州天河公园",
          "remark" : "java developer"
        }
      },
      {
        "_index" : "es_db",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "name" : "李四",
          "sex" : 1,
          "age" : 28,
          "address" : "广州荔湾大厦",
          "remark" : "java assistant"
        }
      },
      {
        "_index" : "es_db",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "name" : "rod",
          "sex" : 0,
          "age" : 26,
          "address" : "广州白云山公园",
          "remark" : "php developer"
        }
      },
      {
        "_index" : "es_db",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : 1.0,
        "_source" : {
          "name" : "admin",
          "sex" : 0,
          "age" : 22,
          "address" : "长沙橘子洲头",
          "remark" : "python assistant"
        }
      },
      {
        "_index" : "es_db",
        "_type" : "_doc",
        "_id" : "5",
        "_score" : 1.0,
        "_source" : {
          "name" : "小明",
          "sex" : 0,
          "age" : 19,
          "address" : "长沙岳麓山",
          "remark" : "java architect assistant"
        }
      }
    ]
  }
}


3.有查询条件

3.1 叶子条件查询(单字段查询条件)

3.1.1 模糊匹配


模糊匹配主要是针对文本类型的字段,文本类型的字段会对内容进行分

词,对查询时,也会对搜索条件进行分词,然后通过倒排索引查找到匹

配的数据,模糊匹配主要通过match等参数来实现


  • match : 通过match关键词模糊匹配条件内容
  • prefix : 前缀匹配regexp : 通过正则表达式来匹配数据
  • match的复杂用法
  • match条件还支持以下参数:
  • query : 指定匹配的值
  • operator : 匹配条件类型
  • and : 条件分词后都要匹配
  • or : 条件分词后有一个匹配即可(默认)
  • minmum_should_match : 指定最小匹配的数量

3.1.2 精确匹配


  • term : 单个条件相等
  • terms : 单个字段属于某个值数组内的值
  • range : 字段属于某个范围内的值
  • exists : 某个字段的值是否存在
  • ids : 通过ID批量查询

3.2 组合条件查询(多条件查询)


组合条件查询是将叶子条件查询语句进行组合而形成的一个完整的查询

条件


  • bool : 各条件之间有and,or或not的关系
  • must : 各个条件都必须满足,即各条件是and的
  • 关系should : 各个条件有一个满足即可,即各条件
  • 是or的关系
  • must_not : 不满足所有条件,即各条件是not的
  • 关系
  • filter : 不计算相关度评分,它不计算_score
  • 即相关度评分,效率更高
  • constant_score : 不计算相关度评分
  • must/filter/shoud/must_not 等的子条件是通
  • 过 term/terms/range/ids/exists/match 等叶子条件为参数的


注:以上参数,当只有一个搜索条件时,must等对应的是一个对象,当

是多个条件时,对应的是一个数组


3.3 连接查询(多文档合并查询)


  • 父子文档查询:parent/child
  • 嵌套文档查询: nested

3.4 DSL查询语言中存在两种:查询DSL(query DSL)和过滤DSL(filter DSL)


它们两个的区别如下图:


image.png


query DSL

在查询上下文中,查询会回答这个问题——“这个文档匹不匹配这个查询,它的

相关度高么?”


如何验证匹配很好理解,如何计算相关度呢?ES中索引的数据都会存储一个

_score分值,分值越高就代表越匹配。另外关于某个搜索的分值计算还是很复杂

的,因此也需要一定的时间。


filter DSL


在过滤器上下文中,查询会回答这个问题——“这个文档匹不匹配?”

答案很简单,是或者不是。它不会去计算任何分值,也不会关心返回的排序问

题,因此效率会高一点。


过滤上下文 是在使用filter参数时候的执行环境,比如在bool查询中使用

must_not或者filter


另外,经常使用过滤器,ES会自动的缓存过滤器的内容,这对于查询来说,会提

高很多性能。一些过滤的情况:


3.5 Query方式查询:案例


根据名称精确查询姓名 term, term查询不会对字段进行分词查询,会

采用精确匹配


注意: 采用term精确查询, 查询字段映射类型属于为keyword.


举例:


POST /es_db/_doc/_search 
{ 
"query": { 
"term": { 
"name": "admin" 
} 
} 
} 
# 等价 SQL: select * from student where name = 'admin' 

根据备注信息模糊查询 match, match会根据该字段的分词器,进行分词查询


举例:


POST /es_db/_doc/_search 
{"from": 0,"size": 2,"query": {"match": {"address": "广州"}}}
# 等价 SQL: SQL: select * from user where address like '%广州%' limit 0, 2 


多字段模糊匹配查询与精准查询 multi_match


POST /es_db/_doc/_search 
{ 
"query":{ 
"multi_match":{ 
"query":"张三", 
"fields":["address","name"] 
} 
} 
} 
# 等价 SQL: select * from student where name like '%张三%' or address like '%张 
三%' 

未指定字段条件查询 query_string , 含 AND 与 OR 条件


POST /es_db/_doc/_search 
{ 
"query":{ 
"query_string":{ 
"query":"(广州) OR 长沙" 
} 
} 
}

指定字段条件查询 query_string , 含 AND 与 OR 条件


POST /es_db/_doc/_search 
{ 
"query":{ 
"query_string":{ 
"query":"admin OR 长沙", 
"fields":["name","address"] 
} 
} 
}

范围查询注:json请求字符串中部分字段的含义


  • range:范围关键字
  • gte 大于等于
  • lte 小于等于
  • gt 大于
  • lt 小于
  • now 当前时间


POST /es_db/_doc/_search 
{ 
"query" : { 
"range" : { 
"age" : { 
"gte":25, 
"lte":28 
} 
} 
} 
} 
# 等价 SQL: select * from user where age between 25 and 28 

分页、输出字段、排序综合查询


POST /es_db/_doc/_search 
{ 
"query" : { 
"range" : { 
"age" : { 
"gte":25, 
"lte":28 
} 
} 
}, 
"from": 0, 
"size": 2, 
"_source": ["name", "age", "book"], 
"sort": {"age":"desc"} 
}

3.6 Filter过滤器方式查询,它的查询不会计算相关性分值,也不会对结果进行排序, 因此效率会高一点,查询的结果可以被缓存。


Filter Context 对数据进行过滤


POST /es_db/_doc/_search 
{ 
"query" : { 
"bool" : { 
"filter" : { 
"term":{ 
"age":25 
} 
} 
} 
} 
} 

总结:


1. match


match:模糊匹配,需要指定字段名,但是输入会进行分词,比如"hello world"会进行拆分为hello和world,然后匹配,如果字段中包含hello或者 world,或者都包含的结果都会被查询出来,也就是说match是一个部分匹配的模糊查询。查询条件相对来说比较宽松。


2. term


term: 这种查询和match在有些时候是等价的,比如我们查询单个的词hello,那么会和match查询结果一样,但是如果查询"hello world",结果就相差很大,因为这个输入不会进行分词,就是说查询的时候,是查询字段分词结果中是否有"hello world"的字样,而不是查询字段中包含"hello world"的字样。当保存数据"hello world"时,elasticsearch会对字段内容进行分词,"hello world"会被分成hello和world,不存在"hello world",因此这里的查询结果会为空。这也是term查询和match的区别。

3. match_phase


match_phase:会对输入做分词,但是需要结果中也包含所有的分词,而且顺序要求一样。以"hello world"为例,要求结果中必须包含hello和world,而且还要求他们是连着的,顺序也是固定的,hello that word不满足,world hello也不满足条件。


4. query_string


query_string:和match类似,但是match需要指定字段名,query_string是在所有字段中搜索,范围更广泛。

三.文档映射


ElasticSearch 中的 mapping 类似 MySQL 中的 schema 信息,说白了就是表的结构信息。


1.ES中映射可以分为动态映射和静态映射


动态映射:


在关系数据库中,需要事先创建数据库,然后在该数据库下创建数据表,并创建表字段、类型、长度、主键等,最后才能基于表插入数据。而Elasticsearch中不需要定义Mapping映射(即关系型数据库的表、字段等),**在文档写入 Elasticsearch时,会根据文档字段自动识别类型,这种机制称之为动态映射。 **


动态映射规则如下:


image.png


静态映射:


静态映射是在Elasticsearch中也可以事先定义好映射,包含文档的各字段类型、分词器等,这种方式称之为静态映射。


2 动态映射

2.1 删除原创建的索引


DELETE /es_db 
# 返回
{
  "acknowledged" : true
}

2.2 创建索引


PUT /es_db
# 返回
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "es_db"
}

2.3 创建文档(ES根据数据类型, 会自动创建映射)


PUT /es_db/_doc/1 
{ 
"name": "Jack", 
"sex": 1, 
"age": 25, 
"book": "java入门至精通", 
"address": "广州白云机场" 
} 
# 返回
{
  "_index" : "es_db",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

2.4 获取文档映射


GET /es_db/_mapping 
# 返回
{
  "es_db" : {
    "mappings" : {
      "properties" : {
        "address" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "age" : {
          "type" : "long"
        },
        "book" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "sex" : {
          "type" : "long"
        }
      }
    }
  }
}


3 静态映射

3.1 删除原创建的索引


DELETE /es_db 

3.2 创建索引


PUT /es_db

3.3 设置文档映射


PUT /es_db 
{ 
"mappings":{ 
"properties":{ 
"name":{"type":"keyword","index":true,"store":true}, 
"sex":{"type":"integer","index":true,"store":true}, 
"age":{"type":"integer","index":true,"store":true}, 
"book":{"type":"text","index":true,"store":true}, 
"address":{"type":"text","index":true,"store":true} 
} 
} 
}
# 返回
{
  "error" : {
    "root_cause" : [
      {
        "type" : "resource_already_exists_exception",
        "reason" : "index [es_db/HvQwVSaGRdy0gHwI_e49DQ] already exists",
        "index_uuid" : "HvQwVSaGRdy0gHwI_e49DQ",
        "index" : "es_db"
      }
    ],
    "type" : "resource_already_exists_exception",
    "reason" : "index [es_db/HvQwVSaGRdy0gHwI_e49DQ] already exists",
    "index_uuid" : "HvQwVSaGRdy0gHwI_e49DQ",
    "index" : "es_db"
  },
  "status" : 400
}

3.4 根据静态映射创建文档


PUT /es_db/_doc/1 
{ 
"name": "Jack", 
"sex": 1, 
"age": 25, 
"book": "elasticSearch入门至精通", 
"address": "广州车陂" 
}
# 返回
{
  "_index" : "es_db",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

3.5 获取文档映射


GET /es_db/_mapping
# 返回
{
  "es_db" : {
    "mappings" : {
      "properties" : {
        "address" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "age" : {
          "type" : "long"
        },
        "book" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "sex" : {
          "type" : "long"
        }
      }
    }
  }
}


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
9天前
|
数据采集 人工智能 运维
从企业级 RAG 到 AI Assistant,阿里云Elasticsearch AI 搜索技术实践
本文介绍了阿里云 Elasticsearch 推出的创新型 AI 搜索方案
106 3
从企业级 RAG 到 AI Assistant,阿里云Elasticsearch AI 搜索技术实践
|
4月前
|
存储 关系型数据库 MySQL
浅谈Elasticsearch的入门与实践
本文主要围绕ES核心特性:分布式存储特性和分析检索能力,介绍了概念、原理与实践案例,希望让读者快速理解ES的核心特性与应用场景。
118 12
|
6天前
|
数据采集 人工智能 运维
从企业级 RAG 到 AI Assistant,阿里云Elasticsearch AI 搜索技术实践
本文介绍了阿里云 Elasticsearch 推出的创新型 AI 搜索方案。
|
3月前
|
存储 JSON 监控
大数据-167 ELK Elasticsearch 详细介绍 特点 分片 查询
大数据-167 ELK Elasticsearch 详细介绍 特点 分片 查询
67 4
|
5月前
|
人工智能 自然语言处理 搜索推荐
阿里云Elasticsearch AI搜索实践
本文介绍了阿里云 Elasticsearch 在AI 搜索方面的技术实践与探索。
19233 21
|
3月前
|
自然语言处理 搜索推荐 Java
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(一)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图
70 0
|
3月前
|
存储 自然语言处理 搜索推荐
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
50 0
|
3月前
|
消息中间件 监控 关系型数据库
MySQL数据实时同步到Elasticsearch:技术深度解析与实践分享
在当今的数据驱动时代,实时数据同步成为许多应用系统的核心需求之一。MySQL作为关系型数据库的代表,以其强大的事务处理能力和数据完整性保障,广泛应用于各种业务场景中。然而,随着数据量的增长和查询复杂度的提升,单一依赖MySQL进行高效的数据检索和分析变得日益困难。这时,Elasticsearch(简称ES)以其卓越的搜索性能、灵活的数据模式以及强大的可扩展性,成为处理复杂查询需求的理想选择。本文将深入探讨MySQL数据实时同步到Elasticsearch的技术实现与最佳实践。
234 0
|
4月前
|
JSON 自然语言处理 算法
ElasticSearch基础2——DSL查询文档,黑马旅游项目查询功能
DSL查询文档、RestClient查询文档、全文检索查询、精准查询、复合查询、地理坐标查询、分页、排序、高亮、黑马旅游案例
|
5月前
|
自然语言处理 Java 关系型数据库
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
179 1