Elasticsearch:使用 Open Crawler 和 semantic text 进行语义搜索

343 阅读8分钟

作者:来自 Elastic Jeff Vestal

了解如何使用开放爬虫与 semantic text 字段结合来轻松抓取网站并使其可进行语义搜索。

我们在这里要做什么?

Elastic Open Crawler 是 Elastic 托管爬虫的后继者。

Semantic text 是 Elastic 的简单入门数据类型,用于启动和运行语义搜索。

两者结合,就像是搜索领域的 “新锐组合”。

接下来,我们将学习如何轻松配置并运行 Open Crawler 来爬取一个网站(以 Search Labs 的博客为例),自动分块并使用 ELSER 为这些网页内容(博客文本)生成稀疏向量嵌入,并运行一些示例搜索,确保一切正常运行。

选择你自己的冒险

Elasticsearch

项目或集群

你首先需要的是 Elasticsearch 集群或无服务器项目。如果你没有,没关系;你可以在 cloud.elastic.co 注册免费试用

创建映射模板。

如果你不想自定义任何映射,Open Crawler 将使用合理的默认值将其在网络上抓取的所有数据索引到 Elasticsearch 中。但是,在我们的例子中,我们希望增强默认映射,以便我们的一些文本可以为其生成稀疏向量。

我们将为索引中的两个关键字段创建一个新的索引模板。其余字段默认设置。

  • 创建一个名为 body_semanticsemantic_text 字段
    • 这将:
      • 从博客正文生成块
      • 使用 ELSER 从块生成稀疏向量
    • 注意:语义文本字段需要 inference API,它告诉 Elasticsearch 如何在提取和搜索时生成嵌入。由于我们在此示例中使用无服务器,因此我们将在 Elasticsearch 中使用默认的 ELSER 推理端点。
      • 如果你不使用 serverless 或想要设置自己的推理端点,ELSER 的文档页面有一个创建新推理端点的示例。
  • 为 “body” 字段添加映射,以包含 “copy_to” 参数,从而将正文复制到我们的语义文本字段。
    • body 字段通常会自动映射到文本。

PUT 索引模板



1.  PUT _index_template/search-labs-template
2.  {
3.    "index_patterns": [
4.      "search-labs-blogs",
5.      "search-labs-blogs*"
6.    ],
7.    "template": {
8.      "settings": {
9.        "index": {
10.          "default_pipeline": "parse_author_and_publish_date"
11.        }
12.      },
13.      "mappings": {
14.        "properties": {
15.          "first_author": {
16.            "type": "keyword"
17.          },
18.          "publish_date": {
19.            "type": "date"
20.          },
21.          "body": {
22.            "type": "text",
23.            "copy_to": "body_semantic"
24.          },
25.          "body_semantic": {
26.            "type": "semantic_text",
27.            "inference_id": "elser-endpoint"
28.          },
29.          "last_crawled_at": {
30.            "type": "date"
31.          }
32.        }
33.      }
34.    }
35.  }


创建空索引

PUT search-labs-blogs

创建摄取管道

爬虫程序在抓取网页时可以提取一些信息。但是,当你需要额外的解析时,你可以配置摄取管道。

我们将配置一个管道来提取以下信息:

  • 从 author 字段中提取发布日期并将其存储在新的 posted_date 字段中
  • 从 list_of_authors 中提取第一作者并将其存储在新的 first_author 字段中
  • 删除 raw_author 和 raw_publish_date

PUT 摄取管道



1.  PUT _ingest/pipeline/parse_author_and_publish_date
2.  {
3.    "processors": [
4.      {
5.        "script": {
6.          "source": """
7.            // If raw_author is null or empty array, set default unknown
8.            if (ctx.raw_author == null || ctx.raw_author.size() == 0) {
9.              ctx.list_of_authors = [];
10.              ctx.first_author = "Unknown";
11.            } else {
12.              // raw_author is already an array from crawler
13.              ctx.list_of_authors = ctx.raw_author;
14.              ctx.first_author = ctx.raw_author[0];  // The first element
15.            }
16.          """
17.        }
18.      },
19.      {
20.        "script": {
21.          "source": """
22.  				// If raw_publish_date is null or empty array, set default to January 1, 1970
23.            if (ctx.raw_publish_date == null || ctx.raw_publish_date.trim().length() == 0) {
24.              ctx.raw_publish_date = "January 1, 1970";
25.            } else {
26.              ctx.raw_publish_date = ctx.raw_publish_date.trim();
27.            }
28.          """
29.        }
30.      },
31.      {
32.        "date": {
33.          "field": "raw_publish_date",
34.          "target_field": "publish_date",
35.          "formats": ["MMMM d, yyyy"],
36.          "timezone": "UTC"
37.        }
38.      },
39.      {
40.        "remove": {
41.          "field": "raw_publish_date",
42.          "ignore_missing": true
43.        }
44.      },
45.      {
46.        "remove": {
47.          "field": "raw_author",
48.          "ignore_missing": true
49.        }
50.      }
51.    ]
52.  }


部署 ELSER

如果你使用的是 Elastic 的 serverless 项目,则可以使用默认的 ELSER 推理端点 (_inference/.elser-2-elasticsearch)。如果这样做,你需要更新索引模板中 body_semantic 的映射。

我们将创建一个新的推理端点,为其提供更多资源,这样非 serverless 的读者也可以享受乐趣!

PUT 新的推理端点



1.  PUT _inference/sparse_embedding/elser-endpoint
2.  {
3.    "service": "elser",
4.    "service_settings": {
5.      "num_allocations": 32,
6.      "num_threads": 1
7.    }
8.  }


Docker

这里只是简单说明一下。你必须在要运行爬虫的计算机或服务器上安装并运行 Docker。

查看 Docker 的入门指南以获取有关启动和运行的帮助。

Open Crawler

下载 Docker 镜像

你可以使用 Elastic 的官方镜像下载并启动 Open Crawler Docker 镜像。



1.  docker run -i -d \
2.  --name crawler \
3.  docker.elastic.co/integrations/crawler:0.2.0


配置爬虫

我们将爬取 Elastic Search Labs 博客。Search Labs 有很多出色的搜索、ML 和 GenAI 内容。但它也链接到 elastic.co 的其他部分。我们将配置爬虫以限制我们的爬取,确保仅索引博客。

Crawler.yaml

  1. 创建一个新的 crawler.yaml 文件并粘贴以下代码
  2. allow 规则,用于 /search-labs/blog URL 模式下的所有内容(包括)
  3. 一个 “拒绝所有” 的规则,用于拦截所有其他 URL。
  4. 使用提取规则提取作者的姓名并将其分配给字段 “authors”。
    1. 有关提取规则示例的更多详细信息,请查看有关测试版的博客。
  5. 在此示例中,我们使用正则表达式模式作为拒绝规则。

将以下代码粘贴到 crawler.yml 中:

crawler.yml



1.  domains:
2.    - url: https://www.elastic.co
3.      seed_urls:
4.        - https://www.elastic.co/search-labs/blog/

6.      crawl_rules:
7.        - policy: allow
8.          type: begins
9.          pattern: "/search-labs/blog"
10.        - policy: deny
11.          type: regex
12.          pattern: ".*"

14.      extraction_rulesets:
15.        - url_filters:
16.            - type: begins
17.              pattern: /search-labs/blog/
18.          rules:

20.            - action: extract
21.              field_name: raw_author
22.              selector: ".Byline_authorNames__bCmvc a[href*='/search-labs/author/']"
23.              join_as: array
24.              source: html

26.            - action: extract
27.              field_name: raw_publish_date
28.              selector: "time.article-published-date"
29.              attribute: "datetime"
30.              join_as: string
31.              source: html

33.  output_sink: elasticsearch
34.  output_index: search-labs-blogs

36.  sitemap_discovery_disabled: true
37.  binary_content_extraction_enabled: false

39.  elasticsearch:
40.    host: http://kubernetes-vm
41.    username: elastic
42.    password: changeme
43.    pipeline: parse_author_and_publish_date
44.    pipeline_enabled: true

46.  log_level: debug


将配置文件复制到正在运行的 docker 容器

运行下面的复制命令:

docker cp crawler.yml crawler:app/config/crawler.yml

启动抓取作业

我们现在可以抓取一些网页了!运行以下命令即可启动它。

docker exec -it crawler bin/crawler crawl config/crawler.yml

注意:你最初可能会在爬虫日志中看到超时。默认情况下,ELSER 部署会缩减为 0 个分配,以减少空闲时的成本。部署需要一分钟才能扩展。

转到文档!

返回 Kibana 中的控制台并输入以下搜索:



1.  GET search-labs-blogs/_search
2.  {
3.    "retriever": {
4.      "standard": {
5.        "query": {
6.          "semantic": {
7.            "field": "body_semantic",
8.            "query": "How do I quantize vectors?"
9.          }
10.        }
11.      }
12.    },
13.    "_source": false,
14.    "fields": [
15.      "title",
16.      "body"
17.    ]
18.  }


我收到的前五个标题是:

  1. Better Binary Quantization vs. Product Quantization - Search Labs
  2. Scalar quantization 101 - Search Labs
  3. RaBitQ binary quantization 101 - Search Labs
  4. Better Binary Quantization (BBQ) in Lucene and Elasticsearch - Search Labs
  5. Understanding Int4 scalar quantization in Lucene - Search Labs

所有查找可以帮助回答我的问题的博客。

Discover

你还可以跳转到 “Discover” 以查看文档表。

设置方法:

  • 单击 “ Data View” 选择器
  • 单击 “Create a data view”
  • 在索引模式框中,输入“search-labs-blogs”
  • 在 “Timestamp” 字段中,选择 “publish_date”
  • 单击 “Save data view to Kibana”

你可能需要更改时间选择器以设置更宽的范围。

  • 单击时间选择器(通常默认为“Last 15 minutes”)
  • 选择 “Last 1 year”

你可以单击左列字段名称旁边的 +,制作一个格式良好的表格,如下所示。

Discover 视图显示了从 Open Crawler 索引的 search labs 博客

按需工作坊

你已经坚持到最后了!为什么不在一个真实的按需工作坊环境中亲自动手实践以上内容呢?
点击此处立即参与。

想要获得 Elastic 认证?了解下一期 Elasticsearch 工程师培训何时举行!

Elasticsearch 包含许多新功能,可帮助您针对自己的用例构建最佳搜索解决方案。深入了解我们的示例笔记本以了解更多信息,开始免费云试用,或立即在本地机器上试用 Elastic。

原文:Semantic search using the Open Crawler and Semantic Text - Elasticsearch Labs