2017-09-07 51 views
0

在elasticsearch中存儲關係數據有哪些選項。我知道以下方法如何在elasticsearch中存儲關係數據

  1. 嵌套對象: - 我不想存儲在嵌套格式的數據,因爲我想在不改變其他文件,如果我使用嵌套的對象則更新一個文檔將在父文件中重複兒童數據。

  2. 親子: - 我不想將數據存儲在單個索引中,但使用父子數據需要在一個索引(不同類型)中存在。我知道這個限制將會在未來版本中被刪除,如https://github.com/elastic/elasticsearch/issues/15613問題所述,但我想要一個適用於5.5版本的解決方案。

除此之外,還有其他方法嗎?

回答

0

還有兩種方法:Denormalizationrunning multiple queries for joins

非規範化會佔用更多空間並增加寫入時間,但您只需運行一個查詢即可檢索數據,因此您的閱讀時間將會提高。由於您不想將數據存儲在單個索引中,因此加入可能會幫助您解決問題。

2

嵌套對象是一個完美的方法。如果您正確更新子對象,則不會在父文檔中重複子對象。 對於我需要維護Master-Child一對多關係的關係數據的其中一個用例,我使用了相同的方法。 我寫了一個無痛腳本更新API添加 & 更新現有嵌套子,而無需創建副本或重複條目父文檔中的對象。

更新答:

下面是一個嵌入式嵌套類型的文檔「孩子的」親子嵌套類型文檔的結構。

{ 
    "parent_id": 1, 
    "parent_name": "ABC", 
    "parent_number": 123, 
    "parent_addr": "123 6th St. Melbourne, FL 32904" 
    "childs": [ 
     { 
     "child_id": 1, 
     "child_name": "PQR", 
     "child_number": 456, 
     "child_age": 10 
     }, 
     { 
     "child_id": 2, 
     "child_name": "XYZ", 
     "child_number": 789, 
     "child_age": 12 
     }, 
     { 
     "child_id": 3, 
     "child_name": "QWE", 
     "child_number": 234, 
     "child_age": 16 
     } 

    ] 
} 

映射將如下:

PUT parent/ 
{ 
    "parent": { 
    "mappings": { 
     "parent": { 
     "properties": { 
      "parent_id": { 
      "type": "long" 
      }, 
      "parent_name": { 
      "type": "text", 
      "fields": { 
       "keyword": { 
       "type": "keyword", 
       "ignore_above": 256 
       } 
      } 
      }, 
      "parent_number": { 
      "type": "long" 
      }, 
      "parent_addr": { 
      "type": "text", 
      "fields": { 
       "keyword": { 
       "type": "keyword", 
       "ignore_above": 256 
       } 
      } 
      }, 
      "child_tickets": { 
      "type": "nested", 
      "properties": { 
       "child_id": { 
       "type": "long" 
       }, 
       "child_name": { 
       "type": "text", 
       "fields": { 
        "keyword": { 
        "type": "keyword", 
        "ignore_above": 256 
        } 
       } 
       }, 
       "child_number": { 
       "type": "long" 
       }, 
       "child_age": { 
       "type": "long" 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
} 

在關係數據庫管理系統,這兩個實體(父母,子女)是由一個家長之間的兩個不同的表到許多關係 - >子。 Parent的id是Child的行的外鍵。 (id是必須爲兩個表)

現在在Elasticsearch中,要索引父文檔,我們必須有id來索引它,在這種情況下,它是parent_id。 指數父文檔查詢(PARENT_ID是我在談論,並有與索引ID(_id文件的ID)= 1):

POST parent/parent/1 
{ 
    "parent_id": 1, 
    "parent_name": "ABC", 
    "parent_number": 123, 
    "parent_addr": "123 6th St. Melbourne, FL 32904" 
} 

現在,加入孩子(一個或多個)父。爲此,您將需要應具有子ID和父ID的子文檔。 要添加一個孩子,父母的ID是必須的。以下是更新查詢來添加新的孩子或更新已經存在的孩子。

POST parent/parent/1/_update 
{ 
    "script":{ 
    "lang":"painless", 
    "inline":"if (!ctx._source.containsKey(\"childs\")) { 
       ctx._source.childs = []; 
       ctx._source.childs.add(params.child); 
      } else { 
       int flag=0; 
       for(int i=0;i<ctx._source.childs.size();i++){ 
        if(ctx._source.childs[i].child_id==params.child.child_id){ 
         ctx._source.childs[i]=params.child; 
         flag++; 
        } 
       } 
       if(flag==0){ 
        ctx._source.childs.add(params.child); 
       } 
      }", 
    "params":{ 
     "child":{ 
       "child_id": 1, 
       "child_name": "PQR", 
       "child_number": 456, 
       "child_age": 10 
      } 
     } 
    } 
} 

給它一個鏡頭。乾杯!

讓我知道你是否需要別的東西。

+0

感謝Hatim,你可以分享你的腳本來存儲嵌套對象而不重複。 – mkalsi

+0

@mkalsi我已經用示例和腳本更新了我的答案。覈實。 –

+0

如果我們的數據集非常大,我們計劃索引2000萬個文檔,那麼內聯腳本的性能如何。 – mkalsi