Elasticsearch数据导入全攻略:从零开始构建强大搜索引擎

本文详细介绍了三种将数据导入Elasticsearch的方法:网络爬虫自动抓取、JSON文件上传和大规模数据API集成,帮助开发者快速构建高效的搜索解决方案。

如何为我的数据启用Elasticsearch?

Elastic App Search是从零开始为数据构建强大搜索功能的最快机制。其中一个主要原因是开发人员有多种选项可以将内容摄取到Elastic App Search中。

直接指向并爬取

将数据导入Elastic App Search的最快方法是使用网络爬虫,该功能在Elastic 7.15中正式推出。网络爬虫允许您识别URL并定义站点地图、爬取规则和文档处理,然后开始爬取。如果您的网站内容处于"可爬取"状态(可通过公共互联网访问、服务器端渲染,并且没有阻止爬虫的robots.txt),在开始爬取后,页面将开始在Elastic App Search中被索引。

爬取ASP.NET Core官方文档(这是更大的docs.microsoft.com平台的一部分)。

根据您的路由结构和内容大小,这可能需要一些时间。之后,您将获得一个完全索引的数据集,可以分析并根据用户需求进行调整。

JSON数据摄取

网络爬虫功能非常强大,能够几乎无需干预地指向数据并建立索引。但是,如果我们有不符合预定义可爬取标准的数据怎么办?也许这些数据根本不是网络内容,而是由其他系统使用和管理的数据?对于这些场景,我们还提供了一次性工作流中摄取数据的能力,例如文件上传和文本粘贴选项。

在这些场景中,用户能够提供代表其数据的JSON文件,并将其上传或粘贴到Web浏览器中。在这两种情况下,都有最大允许内容大小,大约为100 KB的JSON数据。

大规模数据索引

我们已经看到了在不同模式下将数据导入Elastic App Search是多么顺畅。然而,当我们的数据不断变化且规模庞大时,仍然存在"其他所有情况"的使用案例。在这种情况下,有一套定义良好的API可以将内容索引到Elastic App Search中,并启用可重用的方法来更新该内容。

例如,假设我有一个代表美国职业棒球大联盟(MLB)整个历史所有统计数据的数据集,我希望能够以最高性能和可扩展的方式搜索这些数据。我可以创建一个适合我需求的定制流程,根据需要索引和刷新这些数据。

相关数据集目前驻留在本地SQL Server数据库中。SQL Server是由Microsoft创建的关系数据库平台。

我想要做的是索引球员击球和投球统计数据,并能够搜索和分析这些数据。为了实现满足我目标的解决方案,我需要采取几个步骤:

  1. 创建一个流程,将关系数据格式化,以便可以索引到Elastic中(Elastic中的数据以非规范化格式存储,因此我们需要创建一个机制来映射数据)
  2. 创建另一个流程,使用Elastic App Search API实际将这些数据索引到Elastic中
  3. 首先索引一小部分数据样本,在转向整个数据集之前确认我的数据正在按预期方式被索引和存储

以下是我的数据集的行数大致数字:

  • Person: 19,370
  • Batting: 104,324
  • BattingPost: 139,430
  • Pitching: 45,806
  • PitchingPost: 5,445

虽然就行数而言这不是一个巨大的数据集,但我知道我需要创建一个结构,代表每个人的所有击球和所有投球统计数据。这意味着在索引练习完成后,Elastic App Search中将有19,370个相当大的文档。

对于第一步,我将执行数据检索,并将关系数据转换为每个人的结构化文档。我将在此略过细节,但我选择使用.NET 6作为编程语言来检索这些数据并将其序列化为JSON结构,然后将其发送到Elastic App Search API进行索引。

以下是该代码的完整片段:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureServices((_, services) =>
           services.AddDbContextPool<BaseballStatsContext>(options => options.UseSqlServer(
               "Server=.;Database=BaseballStats;Trusted_Connection=True;Application Name=BaseballStatsDb"))).Build();
 
var databaseContext = host.Services.CreateScope().ServiceProvider.GetRequiredService<BaseballStatsContext>();
 
var people = databaseContext.People
    .Include(person => person.Battings)
    .Include(person => person.BattingPosts)
    .Include(person => person.Pitchings)
    .Include(person => person.PitchingPosts)
    .AsSplitQuery()
    .ToList();
 
var chunks = people
    .Select((x, i) => new { Index = i, Value = x })
    .GroupBy(x => x.Index / 100)
    .Select(x => x.Select(v => v.Value).ToList())
    .ToList();
 
JsonSerializerOptions options = new()
{
    ReferenceHandler = ReferenceHandler.IgnoreCycles,
    PropertyNamingPolicy = new LowerCaseNamingPolicy()
};
 
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://baseballsearch.ent.westus2.azure.elastic-cloud.com");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
 
foreach (var chunk in chunks)
{
    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "/api/as/v1/engines/baseball-stats/documents");
    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "");
    string jsonString = JsonSerializer.Serialize(chunk, options);
    request.Content = new StringContent(jsonString, Encoding.UTF8, "application/json");
    client.Send(request);
}

此代码的作用是查询数据库以获取我们所有的个人数据(包括击球和投球的关系),将该数据集分成100个块(目前,文档创建API每个创建事件限制为100个文档),并将每个块POST到我的API端点。运行后,我可以确认所有19,370个文档都已索引到Elastic中。

一旦我的数据进入Elastic,我就能够使用Kibana中的可视化工具收集有关此数据的见解,并为希望搜索此数据的用户构建定制的搜索体验。

按您想要的方式摄取

使用Elastic,您有多种选项可以摄取数据以便能够搜索它。这篇博客文章涵盖了一些这些选项和特定用例,以及何时使用它们。无论您的数据结构如何,或者它位于何处,您都可以放心地知道您可以索引此内容并构建出色的搜索体验。要亲身体验这一点,最好的方法是注册Elastic Cloud的免费试用。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计