2014-01-30 2786 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\"}}"