当前位置: 首页 > 知识库问答 >
问题:

使用 Logstash 使用一个 ElasticSearch 文档中的字段来丰富另一个文档

吉俊德
2023-03-14

假设我有一个包含三种数据的ElasticSearch实例——作者、出版商和图书——都在JSON中。作者数据如下所示:

{
  "document-id": "XYZ",
  "document-type": "author",
  "name": "John Doe",
  "country": "Canada"
}

,发布者数据如下所示:

{
  "document-id": "JKL",
  "document-type": "publisher",
  "name": "Random House"
}

,则书籍数据如下所示:

{
  "document-id": "ABC",
  "document-type": "book",
  "authorId": "XYZ",
  "publisherId": "JKL",
  "title": "Logstash for Dummies"
}

到目前为止,每个都进入了自己的索引。

我想创建一个非规范化的数据版本,以便我可以轻松搜索加拿大作家撰写或兰登书屋出版的所有书籍。我需要支持对作者,出版商和书籍数据的更新,以便如果作者搬到新的国家/地区或更改其名称,非规范化的副本也将更新。

我还需要保留非规范化副本中所有对象的所有字段(即,避免两个文档ID字段之间的冲突,以便两个文档ID值都存在,即使必须重命名一个;publisher.name和author.name也是如此)。所有这些都将用于Kibana报告,据我所知,这些报告对嵌套对象不太支持,尽管它似乎确实有一些支持,这可能会消除我的字段名称冲突问题。

实现这一目标的最佳方式是什么?我看到一些讨论将我引向Logstash聚合过滤器或ElasticSearch输出插件,但我不确定该追求什么。Logstash有必要吗,或者这对于接收管道是可能的吗?

两种文档类型是否需要位于同一索引中才能使其正常工作?书籍应该用作者和出版商的数据“丰富”,还是应该将它们全部合并到第四种文档类型中?

我是ElasticSearch的新手,也是Logstash的新手,因此我非常感谢您提供的任何指导。

谢谢!

(交叉发布自 https://discuss.elastic.co/t/enrich-one-document-with-fields-from-another/208651,五天后没有收到回复。

共有1个答案

洪胤
2023-03-14

最好的方法确实是尝试将所有数据反规范化为“书本”文档。然而,这并不总是理想的,尤其是如果合并的数据(作者、出版商)会随着时间的推移而变化,在这种情况下,您需要更新所有相关的图书文档(通常使用“按查询更新”API),并且可能需要在作者或出版商每次更改时重建完整索引。

正如我所说,既没有简单的答案,也没有对错。它总是取决于您想要支持的用例。

在你的例子中,你可以通过执行两个查询来摆脱,一个从作者和出版商索引中提取ID,然后使用这些ID来查询书籍索引。

例如,如果您需要检索兰登书屋出版的加拿大作者的所有书籍,则首先发出以下查询:

POST _msearch
{ "index" : "authors" }
{ "query" : { "term": { "country": "Canada" }}}
{ "index" : "publisher" }
{ "query" : { "term": { "name": "Random House" }}}

然后使用检索到的文档的ID,您可以向书籍索引发出查询:

POST books/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "terms": {
            "authorId": ["XYZ1", "XYZ2", "XYZ3"]
          }
        },
        {
          "terms": {
            "publisherId": ["ABC1"]
          }
        }
      ]
    }
  }
}

在您的情况下,我显然不会采用父/子或嵌套的方式,因为要保持一切同步,会有太多的开销。

 类似资料:
  • 假设我有两份文件。 一个是有大约2-3页的主模板。第二个只有一段文字与各种风格(粗体,斜体,下划线,字体大小等)。 我想用第二个文档中的段落替换模板中的一个参数。 null

  • 问题内容: 我需要比较同一文档中的2个字段,实际值无关紧要。考虑以下文档: 我需要找到所有未分配主要内容的文档。我无法找到一种方法来比较primary_content_type_id和嵌套的content.content_type_id以确保它们是相同的值。这是我使用脚本尝试过的。我认为我不了解脚本,但这可能是解决此问题的一种方式: 请注意,如果我删除过滤器的脚本部分,并用另一个术语过滤器替换为,

  • 我需要比较同一个文档中的两个字段,其中的实际值无关紧要。考虑这份文件: 我需要查找未分配主要内容的所有文档。我无法找到一种方法将primary_content_type_id与嵌套content.content_type_id进行比较,以确保它们具有相同的值。这就是我尝试使用脚本的方法。我不认为我理解脚本,但这可能是解决这个问题的一种方法: 请注意,如果我删除过滤器的脚本部分,并将其替换为的另一个

  • 问题内容: 有什么方法可以使用Logstash和csv文件从ElasticSearch删除文档?我阅读了Logstash文档,却一无所获,并尝试了一些配置,但是使用操作“删除”却没有任何反应 有人尝试过吗?我应该在配置的输入和过滤器部分添加一些特殊的东西吗?我使用文件插件作为输入,使用csv插件作为过滤器。 问题答案: 绝对可以按照您的建议去做,但是如果您使用的是Logstash 1.5,则需要使

  • 我在编程一个订单提交页面时遇到了一个相当大的问题,该页面的目的是提交一个订单的争议--提供两个字段被填写,但只有当一个字段少于另一个字段时。 基本上,一个是下拉,另一个是争端框,查询如下: 如果DispotestExtBox=“”而下拉框=“请选择...” 一切正常-提交按钮已启用 如果DisportestExtBox!=“”而下拉框=“请选择...” 错误(反之亦然,因此如果填充了Dispone

  • 问题 你有一个HTML文档要从中提取数据,并了解这个HTML文档的结构。 方法 将HTML解析成一个Document之后,就可以使用类似于DOM的方法进行操作。示例代码: File input = new File("/tmp/input.html"); Document doc = Jsoup.parse(input, "UTF-8", "http://example.com/"); Elem