• 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 个文档(行):

    1. FROM sample_data
    2. | LIMIT 3

    使用案例

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

    Title;Descrition;Author;Year;Publisher;Ratings

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

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

    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 本书:

    1. $query = <<<EOD
    2. FROM books
    3. | WHERE author == "Stephen King"
    4. | SORT rating DESC
    5. | LIMIT 10
    6. EOD;
    7. $result = $client->esql()->query([
    8. 'body' => ['query' => $query]
    9. ]);

    Elasticsearch 的 JSON 结果如下所示:

    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. 2002
    18. ],
    19. [
    20. "Stephen King",
    21. "In Blockade Billy, a retired coach...",
    22. "Simon and Schuster",
    23. 5.0,
    24. "Blockade",
    25. 2010
    26. ],
    27. [
    28. "Stephen King",
    29. "A chilling collection of twenty horror stories.",
    30. "Signet Book",
    31. 4.55859375,
    32. "Night Shift (Signet)",
    33. 1979
    34. ],
    35. ...
    36. ]
    37. }

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

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

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

    使用对象接口,我们可以使用属性和索引来访问值。 例如,$result->values[0][4] 返回列表中第一本书 (0) 的标题 (4),$result->values[1][3] 返回列表中第一本书 (0) 的排名分数 (3)第二本书(1)等 请记住,PHP 中数组的索引从零开始。

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

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

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

    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 类,则可以使用它来映射结果,如下所示:

    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. }
    9. $books = $result->mapTo(Book::class); // Array of Book

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

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

    准备好将 RAG 构建到你的应用程序中了吗? 想要尝试使用向量数据库的不同 LLMs?
    Github 上查看我们的 LangChain、Cohere 等示例笔记本,并参加即将开始的 Elasticsearch 工程师培训

  • 相关阅读:
    机器学习第八课--决策树
    Diffie-Hellman的C++语言描述简单实现
    Databend 开源周报第 116 期
    【Qt开发流程】之富文本处理
    Vue 使用 setup 语法糖
    PDF文件太大怎么办?三招教会你PDF文件压缩
    Spring Boot配置类
    Python列表排序
    P1113 杂务题解
    GB28181设备控制和TeleBoot远程启动命令探究
  • 原文地址:https://blog.csdn.net/UbuntuTouch/article/details/137588806