Elasticsearch(三):Elasticvue使用及DSL执行新增、查询操作

Elasticvue使用及DSL执行CURD

  • [1 概述](#1 概述)
  • [2 什么是Elasticsearch DSL](#2 什么是Elasticsearch DSL)
  • [3 基本结构](#3 基本结构)
  • [4 客户端工具介绍](#4 客户端工具介绍)
    • [4.1 索引介绍](#4.1 索引介绍)
    • [4.2 创建简单索引](#4.2 创建简单索引)
    • [4.3 创建相对完整的索引](#4.3 创建相对完整的索引)
    • [4.4 插入数据](#4.4 插入数据)
      • [4.4.1 基本插入操作](#4.4.1 基本插入操作)
      • [4.4.2 批量插入操作](#4.4.2 批量插入操作)
  • [5 常用的DSL查询类型](#5 常用的DSL查询类型)
    • [5.1 match查询](#5.1 match查询)
      • [5.1.1 match工作原理](#5.1.1 match工作原理)
      • [5.1.2 operator 参数](#5.1.2 operator 参数)
        • [5.1.2.1 使用 OR 操作符](#5.1.2.1 使用 OR 操作符)
        • [5.1.2.2 使用 AND 操作符](#5.1.2.2 使用 AND 操作符)
        • [5.1.2.3 注意事项](#5.1.2.3 注意事项)
    • [5.2 match_phrase查询](#5.2 match_phrase查询)
      • [5.2.1 slop参数](#5.2.1 slop参数)
    • [5.3 match_phrase_prefix查询](#5.3 match_phrase_prefix查询)
    • [5.4 multi_match查询](#5.4 multi_match查询)
  • [6 总结](#6 总结)

大家好,我是欧阳方超,可以我的公众号"欧阳方超",后续内容将在公众号首发。

1 概述

Elasticsearch的DSL(Domain Specific Language)是一个功能强大的查询语言,允许用户以JSON格式构建复杂的查询。本文将介绍Elasticsearch DSL的基本概念、结构、常用查询类型及如何在实际应用中使用它。

2 什么是Elasticsearch DSL

Elasticsearch DSL是一种特定领域语言,用于与Elasticsearch进行交互。它提供了一种灵活且强大的方式来构建和执行查询,使用户能够高效地检索和操作数据。DSL查询以JSON格式书写,通常包含以下几个部分:

  1. 请求行:指定要查询的索引。
  2. 请求体:包含具体的查询逻辑。

3 基本结构

一个典型的DSL查询结构如下:

bash 复制代码
GET /index_name/_search
{
  "query": {
    "match": {
      "field": "value"
    }
  }
}

上面的DSL关键部分如下:

  • index_name:要查询的索引名称。
  • _search:搜索操作。
  • query:指定查询条件,通常好汉各种查询类型。

4 客户端工具介绍

在本文进一步深入之前,先介绍一款操作Elasticsearch的客户端工具------Elasticvue,它是一个强大的开源工具,旨在为 Elasticsearch 提供图形化用户界面,帮助用户更高效地管理和查询数据。在客户端工具中操作Elasticsearch DSL会显得很方便,后续操作都将在该工具中进行。可以在Chrome 应用商店中所有该工具并进行安装。

下图是使用Elasticvue连接Elasticsearch后界面:

可以在Elasticvue的"REST"中执行DSL,具体操作为,在下面图左侧方框中写DSL,然后选择请求方式、输入请求路径,点击下方的"发送请求",响应结果会出现右侧方框中。

4.1 索引介绍

Elasticsearch的索引类似于关系型数据库中库的概念,其结构主要包含mapping与setting两部分,settings设置索引的基础参数,包括分词器、分片、慢查询等等,mappings设置索引的字段参数,可以设置根字段类型、子级字段类型、孙级字段类型,还可以设置字段的格式等等。先介绍下如何使用DSL创建索引并插入数据,为后面的查询操作做铺垫。

4.2 创建简单索引

所谓简单索引,就是在创建时不显式指定settings信息的索引。如下创建了名为products的索引,在mappings中指定了该索引中文档将包含的字段name、price、created_at。其中name为text类型,用于全文搜索。text 类型允许进行分析(例如分词和词干提取),适合需要在大文本中进行搜索的字段。price为float类型,created_at为date类型。

bash 复制代码
PUT /products
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "price": {
        "type": "float"
      },
      "created_at": {
        "type": "date"
      }
    }
  }
}

4.3 创建相对完整的索引

为什么这里说的是创建相对完整的索引呢,因为完整的索引还包括分词器等信息,截止目前还没介绍分词器的概念。下面的DSL除了创建mappings外,在settings中还指定了分片数、副本数,均为1,这也是不指定时的默认值。

bash 复制代码
PUT /products
{
  "settings": {
    "index": {
      "number_of_shards": 1,
      "number_of_replicas": 1
    }
  },
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "price": {
        "type": "float"
      },
      "created_at": {
        "type": "date"
      }
    }
  }
}

下图为该段DSL在Elasticvue执行的结果:

4.4 插入数据

4.4.1 基本插入操作

在Elasticsearch中,插入数据通常使用POST请求,并指定要插入的索引和文档内容。以下是一个基本的示例:

bash 复制代码
POST /products/_doc/1
{
  "name": "头套",
  "price": 19.99,
  "created_at": "2024-11-07T12:00:00"
}

在这个示例中:

  • products 是索引名称。
  • _doc 是文档类型(在Elasticsearch 7.x及以上版本中通常使用 _doc)。
  • 1 是文档ID(如果不指定,Elasticsearch会自动生成一个ID)。
  • 文档内容是一个JSON对象,包含产品的名称、价格和创建时间。
    下图为在Elasticvue中执行的结果:

4.4.2 批量插入操作

如果需要批量插入多个文档,可以使用 _bulk API。以下是一个批量插入的示例:

bash 复制代码
POST /_bulk
{ "index": { "_index": "products", "_id": "2" } }
{ "name": "手套", "price": 29.99, "created_at": "2024-11-07T12:00:00" }
{ "index": { "_index": "products", "_id": "3" } }
{ "name": "脖套", "price": 39.99, "created_at": "2024-11-07T12:00:00" }

一个典型的批量插入请求由交替的操作元数据行和文档数据行组成。以下是结构的详细说明:

  • 操作行:这一行指定要执行的操作(例如 index),并包含目标索引和文档 ID 的元数据。
  • 文档行:这一行包含要索引的实际 JSON 文档。
    下图为在Elasticvue中执行后的结果:

    好,到这里数据准备完毕了,可以进行查询操作了。

5 常用的DSL查询类型

5.1 match查询

  • match查询是用于全文检索基本查询类型,它会将输入的查询字符串分析为多个词项,并在指定字段中查找这些词项。
    我们之前创建的products索引中,包含name字段,所以可以执行以下查询来查找包含"手"的文档:
bash 复制代码
{
  "query": {
    "match": {
      "name": "手"
    }
  }
}

下图为在Elasticvue中执行的结果:

上面的例子似乎没有体现出match查询的特点,为此我们再往products索引插入一些数据,以便体现出match查询的特点。

bash 复制代码
PUT /_bulk
{ "index": { "_index": "products", "_id": "6" } }
{ "name": "The quick brown fox jumps over the lazy dog.", "price": 29.99, "created_at": "2024-11-07T12:00:00" }
{ "index": { "_index": "products", "_id": "7" } }
{ "name": "A quick brown fox.", "price": 39.99, "created_at": "2024-11-07T12:00:00" }

5.1.1 match工作原理

前面提到,match查询会将输入的查询字符串分析为多个词项,并在指定字段中查找这些词项。这里详细解释一下。

文档6(_id=6)中name的值为The quick brown fox jumps over the lazy dog. 如果使用标准分析器进行索引(其实使用其他分词器进行分析也是一样的),该分词器的主要功能包括:将输入文本转为小写、根据空格和标点符号将文本拆分为多个词条(token),经过分析后,存储在倒排索引中的分词为:

bash 复制代码
{
  "tokens": [
    {
      "token": "the",
      "start_offset": 0,
      "end_offset": 3,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "quick",
      "start_offset": 4,
      "end_offset": 9,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "brown",
      "start_offset": 10,
      "end_offset": 15,
      "type": "<ALPHANUM>",
      "position": 2
    },
    {
      "token": "fox",
      "start_offset": 16,
      "end_offset": 19,
      "type": "<ALPHANUM>",
      "position": 3
    },
    {
      "token": "jumps",
      "start_offset": 20,
      "end_offset": 25,
      "type": "<ALPHANUM>",
      "position": 4
    },
    {
      "token": "over",
      "start_offset": 26,
      "end_offset": 30,
      "type": "<ALPHANUM>",
      "position": 5
    },
    {
      "token": "the",
      "start_offset": 31,
      "end_offset": 34,
      "type": "<ALPHANUM>",
      "position": 6
    },
    {
      "token": "lazy",
      "start_offset": 35,
      "end_offset": 39,
      "type": "<ALPHANUM>",
      "position": 7
    },
    {
      "token": "dog",
      "start_offset": 40,
      "end_offset": 43,
      "type": "<ALPHANUM>",
      "position": 8
    }
  ]
}

下图为使用Elasticvue对这句英文进行分析的过程:

在搜索时,如果用户输入"the fox",Elasticsearch会对这个输入内容进行分词,得到:

bash 复制代码
{
  "tokens": [
    {
      "token": "the",
      "start_offset": 0,
      "end_offset": 3,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "fox",
      "start_offset": 4,
      "end_offset": 7,
      "type": "<ALPHANUM>",
      "position": 1
    }
  ]
}

此时Elasticsearch会执行这样的逻辑,任何包含"the"或"fox"的文档都会被返回,因此文档6和7都将被返回,如下图所示:

5.1.2 operator 参数

match查询中,还可以通过设置operator参数控制多个搜索词之间的逻辑关系。通过设置此参数,可以决定文档匹配的严格程度。例如,设置为and时,只有同时包含所有指定词条的文档才会被返回。可以将其设置为一下两种值:

  • OR(默认值):只要文档中包含任意一个搜索词,就会被视为匹配。这种设置增加了召回率,但可能会降低精确度,因为会返回包含部分匹配的文档。
  • AND:所有指定的搜索词必须同时出现在文档中,才能被视为匹配。这种设置提高了精确度,因为只有包含所有搜索词的文档才会被返回。
5.1.2.1 使用 OR 操作符

该参数的缺省值为or,因此上图的查询中即使没有使用operator参数来控制匹配逻辑也能查询出多个文档,就是因为执行的是or逻辑。上图中的DSL查询等效于下面的DSL查询:

bash 复制代码
{
  "query": {
    "match": {
      "name": {
        "query": "The fox",
        "operator":"or"
      }
    }
  }
}

在Elasticvue中执行效果如下:

在这个例子中,只要文档中包含"the"、"fox"中的任意一个,文档就被返回。

5.1.2.2 使用 AND 操作符

and操作符会确保所有关键词都必须存在于文档中。

{

"query": {

"match": {

"name": {

"query": "The fox",

"operator":"and"

}

}

}

}

在这个例子中,只有同时包含"the"和"fox"的文档才会被返回。

5.1.2.3 注意事项
  • 使用and操作符时,可能会导致返回结果减少,因为要求更严格。
  • 可以结合使用其他参数,如minimum_should_match,进一步控制匹配条件,例如,可以要求至少有75%的词项出现在文档中,下面的查询中四个词项有三个出现在文档中,符合至少75%匹配的原则,因此相应文档被返回:
bash 复制代码
{
  "query": {
    "match": {
      "name": {
        "query": "The brown fox jump",
        "minimum_should_match": "75%"
      }
    }
  }
}

minimum_should_match还可以指定值为数字,表示至少有几个词项要出现在文档中,下面的查询要求至少有三个词项出现在文档中:

bash 复制代码
{
  "query": {
    "match": {
      "name": {
        "query": "The brown fox jump",
        "minimum_should_match": 3
      }
    }
  }
}

5.2 match_phrase查询

与match不同,match_phrase查询要求文档中的词项按顺序出现,并且可以指定词项之间的间隔(slop),注意词。以下是match_phrase查询的特点:

  • 短语匹配,要求所有词条必须按照指定的顺序紧邻出现(当不指定slop或slop值为0时)
  • 会对搜索词进行分词,但分词后的词项必须按顺序出现在文档中
  • 分词之间位置关系也会被考虑
    如果我们想查找确切短语"精品全盔",可以使用以下查询:
bash 复制代码
{
  "query": {
    "match_phrase": {
      "name": "精品全盔"
    }
  }
}

5.2.1 slop参数

slop参数运行在短语中插入其他词项,从而提供一定程度的灵活性。如果我们希望输入的短语的词项之间有一定数量的词的间隔,可以通过设置slop参数来实现。注意,slop表示词项之间运行的最大间隔数。

为了更清晰地演示slop的使用,在products索引中另准备两个文档,内容如下:

bash 复制代码
{ "index": { "_index": "products", "_id": "8" } }
{ "name": "elasticsearch is very powerful", "price": 29.99, "created_at": "2024-11-07T12:00:00" }
{ "index": { "_index": "products", "_id": "9" } }
{ "name": "elasticsearch powerful very is", "price": 39.99, "created_at": "2024-11-07T12:00:00" }

下面是一个使用slop的查询(值设置为2):

bash 复制代码
{
  "query": {
    "match_phrase": {
      "name": {
        "query":"elasticsearch powerful",
        "slop":2
      }
    }
  }
}

查询结果显示,可以匹配到文档8和9,文档8中elasticsearch跟powerful之间有两个词项,未超过slop设置的最大词项个数2,因此被匹配到,文档9中elasticsearch跟powerful之间没有词项,即有零个词项,也为超过slop最大词项个数2,因为也被匹配到。

5.3 match_phrase_prefix查询

match_phrase_prefix查询用于查找以特定短语开头的文档。它非常适合实现自动补全功能,因为它允许用户输入部分短语,并返回所有以该短语开头的匹配结果。match_phrase_prefix查询的关键特性是允许最后一个词项作为前缀进行匹配。这意味着在输入的短语中,除了前面的词项必须按顺序匹配外,最后一个词项可以匹配任何以该词项为开头的词。以下是对这一特性的详细解释及示例。

以文档4、5为例,它们的name字段的值分别为"防冷冬季男士全盔"、"防冷冬季男士精品全盔",执行以下查询:

bash 复制代码
{
  "query": {
    "match_phrase_prefix": {
      "name": {
        "query":"防冷冬季男士"
      }
    }
  }
}

将返回以下内容:

bash 复制代码
{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 6.6784973,
    "hits": [
      {
        "_index": "products",
        "_id": "4",
        "_score": 6.6784973,
        "_source": {
          "name": "防冷冬季男士全盔",
          "price": 29.99,
          "created_at": "2024-11-07T12:00:00"
        }
      },
      {
        "_index": "products",
        "_id": "5",
        "_score": 5.9029303,
        "_source": {
          "name": "防冷冬季男士精品全盔",
          "price": 39.99,
          "created_at": "2024-11-07T12:00:00"
        }
      }
    ]
  }
}

5.4 multi_match查询

multi_match查询是对单字段match查询的扩展,允许在多个字段中同时进行搜索,这种查询类型非常灵活,可以根据需要指定不同的匹配策略,并且可以结合多个字段来提高搜索结果的相关性。

假设希望在多个字段中(除了name字段外)查询"防冷冬季男士",可以将字段名写入fields后的中括号中,如下所示:

bash 复制代码
{
  "query": {
    "multi_match": {
      "query":"防冷冬季男士",
        "fields":["name"]
    }
  }
}

6 总结

再不停下了文章就显得太长了,所以本篇到此结束,现在来总结一下。Elasticsearch DSL是一种特定领域语言,用于与Elasticsearch进行交互,使用户能够高效地检索和操作数据,同时介绍了用于执行DSL的客户端工具------Elasticvue,它相比Kibana更轻量,可以满足现阶段的使用需求。还介绍DSL插入单条及批量插入数据的操作。最后介绍了match、match_phrase、match_phrase_prefix、multi_match查询,每种都适合不同的场景,可以结合具体场景选择使用。

我是欧阳方超,把事情做好了自然就有兴趣了,如果你喜欢我的文章,欢迎点赞、转发、评论加关注。我们下次见。

相关推荐
Gold Steps.25 分钟前
基于 Gitlab、Jenkins与Jenkins分布式、SonarQube 、Nexus 的 CiCd 全流程打造
运维·ci/cd·gitlab·jenkins
拓端研究室1 小时前
专题:2025机器人产业深度洞察报告|附136份报告PDF与数据下载
大数据·人工智能·物联网
阿里云大数据AI技术2 小时前
NL2SQL 再创佳绩!阿里云论文中选 SIGMOD 2025
大数据·人工智能·云计算
是小pa丫3 小时前
ElasticSearch重置密码
elasticsearch
庄小焱4 小时前
【离线数仓项目】——电商域ADS层开发实战
大数据
庄小焱4 小时前
【离线数仓项目】——离线大数据系统设计
大数据
南城尽相思5 小时前
es的自定义词典和停用词
elasticsearch·搜索引擎
吃手机用谁付的款5 小时前
基于hadoop的竞赛网站日志数据分析与可视化(下)
大数据·hadoop·python·信息可视化·数据分析
孟猛20236 小时前
使用 C++ 调用 Elasticsearch API
elasticsearch
线条16 小时前
Spark 单机模式安装与测试全攻略
大数据·分布式·spark