2014-01-30 2787 views
8

我使用elasticsearch作爲文檔數據庫,我創建的每條記錄都有一個系統用於記錄標識的guid標識。業務人員希望提供一項功能,讓用戶擁有基於日期的自己的自動文件名約定,以及今日/月迄今爲止創建了多少條記錄。如何在Elasticsearch數據庫中創建唯一約束?

我需要的是防止重複的用戶文件名。有沒有辦法將索引字段設置爲唯一的?像一個SQL唯一約束?

+2

我相信只有唯一約束適用於'_id'場 –

+1

你的問題是錯誤的,elasticsearch不是一個資料庫,但基於Apache Lucene的,它不支持這樣的功能的搜索引擎。同時請記住,ES實時「接近」。 –

回答

8

您需要使用應該是唯一的字段作爲文檔的ID。默認情況下,具有現有ID的新文檔將覆蓋具有相同ID的現有文檔,但如果已存在具有相同ID的文檔,則可以切換至op_type=create以取回錯誤。

雖然沒有辦法與任意字段具有相同的行爲,但只有_id字段以這種方式工作。我可能會考慮在應用層而不是在elasticsearch中處理這個邏輯。

+0

我建議有一個單獨的集合/類型,它只是一個指向原始文檔的指針...這樣你的原稿仍然會有uuid,並且你甚至可以將獨特的名稱作爲原件中的一個字段,單獨的類型/文件將作爲原件的唯一索引。 – Tracker1

2

一種解決方案是使用uniqueId字段值指定文檔ID,並使用op_type=create,同時將文檔存儲在ES中。有了這個,您可以確保您的uniqueId字段具有唯一的價值,並且不會被其他相同的有價值的文檔覆蓋。

爲此,elasticsearch文件說:

索引操作也接受可用於強制創建操作的op_type,允許「提出,如果缺失」行爲。使用create時,如果索引中已存在由該id創建的文檔,則索引操作將失敗。

以下是使用op_type參數的例子:

$ curl -XPUT 'http://localhost:9200/es_index/es_type/unique_a?op_type=create' -d '{ 
    "user" : "kimchy", 
    "uniqueId" : "unique_a" 
}' 

如果你運行上面的要求是好的,但下一次運行它會給你一個錯誤。

0

另一種方法可能是通過集成自動遞增整數來生成應存儲在唯一字段中的字符串。通過這種方式,您可以從一開始就確保您的字段值是唯一的。

你會把你的文件名,這樣在一起:

<current day/month>_<auto-incremented integer> 

自動遞增的整數不會被Elasticsearch本身支持的,但你可以使用這個approach模仿他們。如果您碰巧使用node.js,則可以使用es-sequence模塊。

1

您可以在希望具有唯一約束的列中使用_id。 這是使用postgresql的示例河流。您可以根據您的使用情況更改數據庫驅動程序/數據庫URL。

curl -XPUT localhost:9200/_river/simple_jdbc_river/_meta -d "{\"type\":\"jdbc\",\"jdbc\":{\"strategy\":\"simple\",\"poll\":\"1s\",\"driver\":\"org.postgresql.Driver\",\"url\":\"jdbc:postgresql://DB-URL/DB-INSTANCE\",\"user\":\"USERNAME\",\"password\":\"PASSWORD\",\"sql\":\"select t.id as _id,t.name from topic as t \",\"digesting\" : true},\"index\":{\"index\":\"jdbc\",\"type\":\"topic_jdbc_river1\"}}"