当前位置: 首页 > 面试题库 >

Logstash-> Elasticsearch-更新非规范化数据

赵超
2023-03-14
问题内容

用例说明

我们有一个关系数据库,其中包含有关我们日常运营的数据。目的是允许用户使用全文本搜索引擎来搜索重要数据。数据经过规范化,因此不是进行全文查询的最佳形式,因此,其想法是对数据的一部分进行规范化,然后将其实时复制到Elasticsearch,这使我们能够创建快速而准确的搜索应用程序。

我们已经有了一个启用数据库操作(插入,更新,删除)事件搜索的系统。这些事件仅包含已更改的列和主键(在更新中,我们没有得到整个行)。Logstash已经为每个事件得到通知,因此这部分已经得到处理。

实际问题

现在我们要解决我们的问题。由于计划是对数据进行非规范化,因此我们必须确保将父对象的更新传播到Elasticsearch中的非规范化子对象。我们如何配置logstash来做到这一点?

假设我们Employees在Elasticsearch中维护一个列表。每个Employee都分配给一个Company。由于数据是非规范化的(出于快速搜索的目的),每个数据Employee还带有的名称和地址Company。更新会更改a的名称Company-
我们如何配置logstash来更新Employees分配给的所有公司名称Company

补充说明

@Darth_Vader:我们面临的问题是,我们得到一个事件a
Company发生了变化,但是我们希望Employee在Elasticsearch中修改类型的文档,因为它们本身携带有关公司的数据。您的回答期望我们会为每一个都发生一个事件Employee,事实并非如此。

也许这将使其更加清晰。我们在Elasticsearch中有3名员工:

{type:'employee',id:'1',name:'Person 1',company.cmp_id:'1',company.name:'Company A'}
{type:'employee',id:'2',name:'Person 2',company.cmp_id:'1',company.name:'Company A'}
{type:'employee',id:'3',name:'Person 3',company.cmp_id:'2',company.name:'Company B'}

然后在源数据库中发生更新。

UPDATE company SET name = 'Company NEW' WHERE cmp_id = 1;

我们在logstash中得到一个事件,它表示如下内容:

{type:'company',cmp_id:'1',old.name:'Company A',new.name:'Company NEW'}

然后,应将其传播到Elasticsearch,以使最终的雇员为:

{type:'employee',id:'1',name:'Person 1',company.cmp_id:'1',company.name:'Company NEW'}
{type:'employee',id:'2',name:'Person 2',company.cmp_id:'1',company.name:'Company NEW'}
{type:'employee',id:'3',name:'Person 3',company.cmp_id:'2',company.name:'Company B'}

请注意,该字段已 company.name 更改。


问题答案:

对于我在这里发布的内容,我建议采用类似的解决方案,即使用http输出插件以便通过查询对Employee索引的查询来发布更新。查询将如下所示:

POST employees/_update_by_query
{
  "script": {
    "source": "ctx._source.company.name = params.name",
    "lang": "painless",
    "params": {
      "name": "Company NEW"
    }
  },
  "query": {
    "term": {
      "company.cmp_id": "1"
    }
  }
}

因此,您的Logstash配置应如下所示:

input {
  ... 
}
filter {
  mutate {
    add_field => {
      "[script][lang]" => "painless"
      "[script][source]" => "ctx._source.company.name = params.name"
      "[script][params][name]" => "%{new.name}"
      "[query][term][company.cmp_id]" => "%{cmp_id}"
    }
    remove_field => ["host", "@version", "@timestamp", "type", "cmp_id", "old.name", "new.name"]
  }
}
output {
  http {
    url => "http://localhost:9200/employees/_update_by_query"
    http_method => "post"
    format => "json"
  }
}


 类似资料:
  • 问题内容: 我正在使用Ruby on Rails 3.0.7和MySQL5。在我的应用程序中,我有两个数据库表,即TABLE1和TABLE2,并且出于性能原因,我对TABLE2中的某些数据进行了非规范化,因此我在该表中重复了TABLE1的值。现在,在TABLE1中,我需要更新一些涉及的值,当然,我还必须在TABLE2中正确地更新非规范化的值。 我该如何以高效的方式更新这些值? 也就是说,如果TAB

  • 非规范化数据不存储规范化的数据。换句话说非规范化意味着相同数据的多个拷贝同时存在。 上一章中,我们在帖子中非规范化评论总数,以避免每次都加载所有的评论。在数据建模意义上说这是冗余的,因为我们可以通过计数每个评论,随时计算出该总数(当不考虑运行速度)。 非规范化通常意味着额外的开发工作。在例子中,我们每次添加或删除评论时,还需要同时更新相关的帖子,以确保 commentsCount 字段保持准确。这

  • 问题内容: 出于性能原因,我有一个非规范化的数据库,其中某些表包含从其他表的许多行聚合而来的数据。我想通过使用SQLAlchemy事件来维护此非规范化数据缓存。举例来说,假设我正在编写论坛软件,并希望每个人都有一个专栏来跟踪线程中所有注释的组合词数,以便有效地显示该信息: 因此,每次插入注释时(为简单起见,我们永远不要编辑或删除注释),我们希望更新关联对象的属性。所以我想做类似的事情 因此,当我插

  • 我阅读了cassandra数据建模,除了非规范化数据可能会发生变化之外,一切都很清楚。我如何同步它?当用户电子邮件更改时,更新的方法是什么: < code>groupname是组的一部分,数据模型中的用户可能不知道任何组,因此在用户更改后无法更新电子邮件。 下面描述的解决方案是否合适? 向用户模型中添加一列(类型

  • 问题内容: 我有一个简单的表,其中包含学生编号和相应的教师编号,并且需要对它进行规范化,以输入到旧版系统中。 例如,下面是数据现在的样子: 我希望它看起来像这样,将每个Teacher分成一个单独的列,从左到右填充各列。一个业务规则是,每个学生最多只能有六位老师: 原始表中有10,000多行,因此我需要以编程方式执行此操作。谢谢! 问题答案: 您可以使用数据透视。您还需要“排名”您的老师1-6。请参

  • 问题内容: 好的,我刚开始使用Firebase。我已阅读:https://www.firebase.com/docs/data- structure.html, 并且已阅读:https://www.firebase.com/blog/2013-04-12-denormalizing- is- normal.html 所以我很困惑,因为一个似乎与另一个矛盾。您可以按层次结构组织数据,但是如果您想使其