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查询,每种都适合不同的场景,可以结合具体场景选择使用。

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

相关推荐
java1234_小锋22 分钟前
ElasticSearch如何做性能优化?
大数据·elasticsearch·性能优化
Tester_孙大壮32 分钟前
运维相关知识科普
大数据·运维·数据库
xserver22 小时前
hadoop搭建
大数据·linux·hadoop
lifeng43219 小时前
Jenkins集成部署(图文教程、超级详细)
运维·jenkins
小刘鸭!10 小时前
Flink中并行度和slot的关系——任务和任务槽
大数据·flink
无所不在的物质10 小时前
Jenkins基础教程
运维·云原生·自动化·jenkins
LI JS@你猜啊11 小时前
Elasticsearch 集群
大数据·服务器·elasticsearch
筒栗子11 小时前
复习打卡大数据篇——Hadoop HDFS 03
大数据·hadoop·hdfs
SelectDB14 小时前
Apache Doris 创始人:何为“现代化”的数据仓库?
大数据·数据库·云原生
SelectDB14 小时前
飞轮科技荣获中国电信星海大数据最佳合作伙伴奖!
大数据·数据库·数据分析