如何在Elasticsearch数据库中创建唯一约束?

时间:2014-01-30 15:56:48

标签: elasticsearch

我使用elasticsearch作为文档数据库,我创建的每个记录都有一个系统用于记录ID的guid id。商务人士希望提供一项功能,让用户根据日期拥有自己的自动文件名约定,以及当天/月创建的记录数。

我需要的是防止重复的用户文件名。有没有办法将索引字段设置为唯一?像sql唯一约束?

5 个答案:

答案 0 :(得分:12)

您需要使用应该是唯一的字段作为文档的ID。默认情况下,具有现有ID的新文档将覆盖具有相同ID的现有文档,但如果已存在具有相同ID的文档,则可以切换到op_type=create以返回错误。

但是没有办法在任意字段中使用相同的行为,只有_id字段以这种方式工作。我可能会考虑在应用层而不是在elasticsearch中处理这个逻辑。

答案 1 :(得分:2)

一种解决方案是使用uniqueId字段值指定文档ID,并在ES中存储文档时使用op_type=create。有了这个,您可以确保您的uniqueId字段具有唯一值,并且不会被其他同值文档覆盖。

为此,elasticsearch文件说:

  

索引操作还接受可用于强制创建操作的op_type,允许“put-if-absent”行为。使用create时,如果索引中已存在该id的文档,则索引操作将失败。

以下是使用op_type参数的示例:

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

如果您运行上述请求即可,但下次运行会给您一个错误。

答案 2 :(得分:1)

您可以在要使用唯一约束的列中使用_id。 以下是使用postgresql的示例河流。 Yo可以根据您的使用情况更改数据库驱动程序/ DB-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\"}}"

答案 3 :(得分:1)

ES 7.5 而言,没有这样的额外“约束”可使用映射中的自定义字段来确保唯一性。

但是您仍然可以通过自己的应用程序UUID来解决它,该应用程序可以直接明确用作_id(这是唯一的)来实现您的目标。

PUT <your_index_name>/_doc/<your_app_uuid>
{
  "a_field": "a_value"
}

答案 4 :(得分:0)

另一种方法可能是生成存储在字段中的字符串,该字段应该是唯一的,通过集成自动递增整数。这样,您可以从一开始就确保您的字段值是唯一的。

你可以像这样把你的文件名放在一起:

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

Elasticsearch本身不支持自动递增整数,但您可以使用此approach来模仿它们。如果您碰巧使用node.js,则可以使用es-sequence模块。