Elasticsearch:从 ES|QL 到 PHP 对象

作者:来自 Elastic Enrico Zimuel

从 elasticsearch-php v8.13.0 开始,你可以执行 ES|QL 查询并将结果映射到 stdClass 或自定义类的 PHP 对象。

ES|QL

ES|QL 是 Elasticsearch 8.11.0 中引入的一种新的 Elasticsearch 查询语言。 目前,它在技术预览版中可用。 它提供了一种强大的方法来过滤、转换和分析存储在 Elasticsearch 中的数据。

它利用 "管道" (|) 逐步操作和转换数据。 这种方法允许用户组合一系列操作,其中一个操作的输出成为下一个操作的输入,从而实现复杂的数据转换和分析。

例如,以下查询返回 sample_data 索引的前 3 个文档(行):

css 复制代码
1.  FROM sample_data
2.  | LIMIT 3

使用案例

为了说明官方 PHP 客户端中开发的 ES|QL 功能,我们在 Elasticsearch 中存储了包含 81,828 本书 (54.4 MB) 的 CSV 文件,其中包括以下信息:

ini 复制代码
Title;Descrition;Author;Year;Publisher;Ratings

我们从公开的亚马逊图书评论数据集中提取了此列表。

我们使用以下 Elasticsearch 映射创建了一个 books 索引:

arduino 复制代码
1.  'mappings' : {
2.      'properties': {
3.          'title': {
4.              'type': 'text'
5.          },
6.          'description': {
7.              'type': 'text'
8.          },
9.          'author': {
10.              'type': 'text'
11.          },
12.          'year': {
13.              'type': 'short'
14.          },
15.          'publisher': {
16.              'type': 'keyword'
17.          },
18.          'rating': {
19.              'type': 'half_float'
20.          }
21.      }
22.  }

rating 值是从 2.9 GB 的 Books_ rating.csv 文件中获取的排名评论的平均值。

这里您可以找到我们用于批量导入 Elasticsearch 中所有书籍的 PHP 脚本。 使用 PHP 8.2.17 的批量操作需要 7 秒和 28 MB RAM。 根据建议的映射,Elasticsearch 中的索引大小约为 62 MB。

映射到对象或自定义类

我们可以使用 esql()->query() 端点在 PHP 中执行 ES|QL 查询。 该查询的结果是一个表数据结构。 这是使用 columns 和 valuse 字段以 JSON 形式表示的。 在 columns 字段中,我们有 name 和 type 定义。

下面是一个 ES|QL 查询示例,用于检索按用户排名评论排序的 Stephen King 撰写的前 10 本书:

ini 复制代码
1.  $query = <<<EOD
2.      FROM books
3.      | WHERE author == "Stephen King"
4.      | SORT rating DESC
5.      | LIMIT 10
6.  EOD;

8.  $result = $client->esql()->query([
9.      'body' => ['query' => $query]
10.  ]);

Elasticsearch 的 JSON 结果如下所示:

less 复制代码
1.  {
2.      "columns": [3.          { "name": "author", "type": "text" },4.          { "name": "description", "type": "text" },5.          { "name": "publisher", "type": "keyword" },6.          { "name": "rating", "type": "double" },7.          { "name": "title", "type": "text" },8.          { "name": "year", "type": "integer" }9.      ],
10.      "values": [11.          [12.              "Stephen King",13.              "The author ...",14.              "Turtleback",15.              5.0,16.              "How writers write",17.              200218.          ],
19.          [20.              "Stephen King",21.              "In Blockade Billy, a retired coach...",22.              "Simon and Schuster",23.              5.0,24.              "Blockade",25.              201026.          ],
27.          [28.              "Stephen King",29.              "A chilling collection of twenty horror stories.",30.              "Signet Book",31.              4.55859375,32.              "Night Shift (Signet)",33.              197934.          ],
35.          ...
36.      ]
37.  }

在此示例中,我们有与一本书相关的 6 个属性(作者、描述、出版商、评级、标题、年份)和 10 个结果,所有书籍均由 Stephen King 撰写。

此处报告了 ES|QL 中所有支持的类型的列表。

$result 响应对象可以作为数组、字符串或对象进行访问(请参阅此处了解更多信息)。

使用对象接口,我们可以使用属性和索引来访问值。 例如, <math xmlns="http://www.w3.org/1998/Math/MathML"> r e s u l t − > v a l u e s [ 0 ] [ 4 ] 返回列表中第一本书 ( 0 ) 的标题 ( 4 ) , result->values[0][4] 返回列表中第一本书 (0) 的标题 (4), </math>result−>values[0][4]返回列表中第一本书(0)的标题(4),result->values[1][3] 返回列表中第一本书 (0) 的排名分数 (3)第二本书(1)等 请记住,PHP 中数组的索引从零开始。

这个接口对于某些用例来说已经足够好了,但大多数时候我们希望得到一个对象数组。

要将结果映射到对象数组中,我们可以使用 elasticsearch-php 的新 mapTo() 功能。

该函数可直接在Elasticsearch 响应对象中使用。 这意味着你可以按如下方式访问它:

perl 复制代码
1.  $books = $result->mapTo(); // Array of stdClass
2.  foreach ($books as $book) {
3.      printf(
4.          "%s, %s, %d, Rating: %.2f\n",
5.          $book->author,
6.          $book->title,
7.          $book->year,
8.          $book->rating
9.      );
10.  }

如果你有自定义 Book 类,则可以使用它来映射结果,如下所示:

php 复制代码
1.  class Book
2.  {
3.      public string $author;
4.      public string $title;
5.      public string $description;
6.      public int $year;
7.      public float $rating;
8.  }

10.  $books = $result->mapTo(Book::class); // Array of Book

如果你的类除了 ES|QL 结果中包含的属性之外还有其他属性,那么这也将起作用。 mapTo() 函数将仅使用作为 ES|QL 结果的列返回的属性。

您可以在此处下载本文中报告的所有示例。

准备好将 RAG 构建到你的应用程序中了吗? 想要尝试使用向量数据库的不同 LLMs?

Github 上查看我们的 LangChain、Cohere 等示例笔记本,并参加即将开始的 Elasticsearch 工程师培训

相关推荐
丶213616 小时前
【大数据】Elasticsearch 实战应用总结
大数据·elasticsearch·搜索引擎
闲人编程17 小时前
elasticsearch实战应用
大数据·python·elasticsearch·实战应用
世俗ˊ21 小时前
Elasticsearch学习笔记(3)
笔记·学习·elasticsearch
weixin_466286681 天前
ElasticSearch入门
大数据·elasticsearch·搜索引擎
Elasticsearch1 天前
使用模拟和真实的 Elasticsearch 来测试你的 Java 代码
elasticsearch
沐曦可期1 天前
Elasticsearch学习记录
大数据·学习·elasticsearch
alfiy1 天前
ElasticSearch学习笔记(三)Ubuntu 2204 server elasticsearch集群配置
笔记·学习·elasticsearch
hengzhepa1 天前
ElasticSearch备考 -- 多字段查询
学习·elasticsearch·搜索引擎·全文检索·es
hengzhepa2 天前
ElasticSearch 备考 -- 备份和恢复
大数据·学习·elasticsearch·搜索引擎·es
hengzhepa2 天前
ElasticSearch备考 -- Update by query
大数据·学习·elasticsearch·搜索引擎·全文检索