【问题标题】:How to create unique constraint in Elasticsearch database?如何在 Elasticsearch 数据库中创建唯一约束?
【发布时间】:2014-02-23 00:54:40
【问题描述】:

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

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

【问题讨论】:

  • 我相信唯一唯一的约束适用于_id 字段
  • 你的问题错了,elasticsearch不是数据库,而是基于Apache Lucene的搜索引擎,不支持这些功能。还要记住,ES 是“接近”实时的。

标签: elasticsearch


【解决方案1】:

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

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

【讨论】:

  • 我建议有一个单独的集合/类型,它只是指向原始文档的指针......这样你的原件仍然会有 uuid,你甚至可以将唯一名称作为一个字段原件,单独的类型/文档将作为原件的唯一索引。
【解决方案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"
}'

如果你运行上面的请求是可以的,但是下次运行它会报错。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      但您仍然可以通过您自己的应用程序 UUID 绕过它,它可以直接显式用作_id(这是唯一的隐式)来实现您的目标。

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

      【讨论】:

        【解决方案5】:

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

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-06-27
          • 2013-05-21
          • 1970-01-01
          • 2010-09-09
          • 1970-01-01
          • 1970-01-01
          • 2012-09-17
          • 2012-07-30
          相关资源
          最近更新 更多