簡體   English   中英

Logstash-> Elasticsearch-更新非規范化數據

[英]Logstash -> Elasticsearch - update denormalized data

用例說明

我們有一個關系數據庫,其中包含有關我們日常運營的數據。 目的是允許用戶使用全文本搜索引擎來搜索重要數據。 數據經過規范化,因此不是進行全文查詢的最佳形式,因此,其想法是對數據的一部分進行規范化,然后將其實時復制到Elasticsearch,這使我們能夠創建快速而准確的搜索應用程序。

我們已經有了一個啟用數據庫操作(插入,更新,刪除) 事件搜索的系統。 事件僅包含已更改的列和主鍵(在更新中,我們沒有得到整行)。 Logstash已經為每個事件得到通知,因此這部分已經得到處理。


實際問題

現在我們要解決我們的問題。 由於計划是對數據進行非規范化,因此我們必須確保將父對象的更新傳播到Elasticsearch中的非規范化子對象。 我們如何配置logstash來做到這一點?

假設我們維護了Elasticsearch中的Employees列表。 每個Employee被分配到一個Company 由於數據是規格化(對於更快的搜索的目的),每個Employee也攜帶的名稱和地址Company 更新會更改Company名稱- 我們如何配置logstash來更新分配給Company所有Employees的公司名稱?


補充說明

@Darth_Vader:我們面臨的問題是,我們收到了一個Company發生變更的事件,但是我們希望在Elasticsearch中修改Employee類型的文檔,因為它們本身攜帶有關公司的數據。 您的答案期望我們會為每個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"
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM