Clinton Gormley


ElasticSearchX::UniqueKey - Track unique keys in ElasticSearch


version 0.03


    use ElasticSearch();
    use ElasticSearchX::UniqueKey();

    my $es   = ElasticSearch->new();
    my $uniq = ElasticSearchX::UniqueKey->new( es => $es );


    $created = $uniq->create( $key_name, $key_id );
    $deleted = $uniq->delete( $key_name, $key_id );
    $exists  = $uniq->exists( $key_name, $key_id );
    $updated = $uniq->update( $key_name, $old_id, $new_id );

    %failed  = $uniq->multi_create(
        $key_name_1 => $key_id_1,
        $key_name_2 => $key_id_2,

        $key_name_1 => $key_id_1,
        $key_name_2 => $key_id_2,

    %failed = $uniq->multi_update(
        { key_1 => 'old', key_2 => 'old' },
        { key_1 => 'new', key_2 => 'new' },

    %failed  = $uniq->multi_exists(
        $key_name_1 => $key_id_1,
        $key_name_2 => $key_id_2,

    $uniq->delete_type( $key_name );


The only unique key available in ElasticSearch is the document ID. Typically, if you want a document to be unique, you use the unique value as the ID. However, sometimes you don't want to do this. For instance, you may want to use the email address as a unique identifier for your user accounts, but you also want to be able to link to a user account without exposing their email address.

ElasticSearchX::UniqueKey allows you to keep track of unique values by maintaining a dedicated index which can contain multiple types. Each type represents a different key name (so a single index can be used to track multiple unique keys).



    my uniq = ElasticSearchX::UniqueKey->new(
        es      => $es,         # ElasticSearch instance, required
        index   => 'index',     # defaults to 'unique_key',

new() returns a new instance of ElasticSearchX::UniqueKey. The unique keys are stored in the specified index, which is setup to be very efficient for this purpose, but not useful for general storage.

You must call "bootstrap()" to create your index before first using it, otherwise it will not be setup correctly. See "bootstrap()" for how to initiate your index.

You don't need to setup your key_names (ie your types) - these will be created automatically.


    $created = $uniq->create( $key_name, $key_id );

Returns true if the key_name/key_id combination didn't already exist and it has been able to create it. Returns false if it already exists.


    $deleted = $uniq->delete( $key_name, $key_id );

Returns true if the key_name/key_id combination existed and it has been able to delete it. Returns false if it didn't already exist.


    $exists = $uniq->exists( $key_name, $key_id );

Returns true or false depending on whether the key_name/key_id combination exists or not.


    $updated = $uniq->update( $key_name, $old_id, $new_id );

First tries to create the new combination key_name/new_id, otherwise returns false. Once created, it then tries to delete the key_name/old_id, and returns true regardless of whether it existed previously or not.


    %failed = $uniq->multi_create(
        $key_name_1 => $key_id_1,
        $key_name_2 => $key_id_2,

Use "multi_create()" to create several entries at the same time (each $key_name must be different). If it fails to create all the entries, then it will remove any entries that it succeeded in creating, and return a hash of the entries which failed.


        $key_name_1 => $key_id_1,
        $key_name_2 => $key_id_2,

Use "multi_delete()" to delete several entries at the same time (each $key_name must be different). Returns 1 whether the entries exist or not.


    %failed = $uniq->multi_update( \%old, \%new );

"multi_update()" first tries to create the new keys, then deletes the old keys. Returns a hash of any entries that couldn't be created.


    %failed = $uniq->multi_exists(
        $key_name_1 => $key_id_1,
        $key_name_2 => $key_id_2,

Returns a hash of any entries that don't exist.


    $uniq->bootstrap( %settings );

This method will create the index, if it doesn't already exist. By default, the index is setup with the following %settings:

        number_of_shards     => 1,
        auto_expand_replicas => '0-all',

In other words, it will have only a single primary shard (instead of the ElasticSearch default of 5), and a replica of that shard on every ElasticSearch node in your cluster.

If you pass in any %settings then the defaults will not be used at all.

See Index Settings for more.



Deletes the index. You will lose your data!


    $uniq->delete_type( $key_name )

Deletes the type associated with the key_name. You will lose your data!


    $index = $uniq->index

Read-only getter for the index value


    $es = $uniq->es

Read-only getter for the ElasticSearch instance.




This is a new module, so there will probably be bugs, and the API may change in the future.

If you have any suggestions for improvements, or find any bugs, please report them to I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.


The full test suite requires a live ElasticSearch cluster to run. CPAN testers doesn't support this. You can see full test results here:!/clintongormley/ElasticSearchX-UniqueKey/builds.

To run the full test suite locally, run it as:

    perl Makefile.PL
    ES_HOME=/path/to/elasticsearch make test


You can find documentation for this module with the perldoc command.

    perldoc ElasticSearchX::UniqueKey

You can also look for information at:


Clinton Gormley <>


This software is copyright (c) 2012 by Clinton Gormley.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.