Permalink
Browse files

Added a 'transform' callback to reindex()

  • Loading branch information...
1 parent aeb569a commit 2829d6b4eb975be2425fc964d954639c813dcfa8 @clintongormley committed Aug 4, 2012
@@ -58,13 +58,31 @@ L<reindex()|Elastic::Model::Index/reindex()>, but you can disable it with:
$index->reindex( 'myapp:v1', repoint_uids => 0 );
-=head1 TODO
+=head1 CHANGING DOC STRUCTURE WHILE REINDEXING
-=over
+If the structure of your Doc class has changed, then you may need to change
+the structure of each doc before reindexing it. To do so, you can pass
+a C<transform> callback.
-=item *
+The C<transform> sub is called before any other changes are made to your doc,
+and is passed the C<$doc> as its only parameter. It should return the new
+C<$doc>.
+
+For instance, to convert the single-value C<tag> field to an array of C<tags>,
+you could do:
-Make custom changes to docs while reindexing
+ $index->reindex(
+ 'new_index',
+ 'transform' => sub {
+ my $doc = shift;
+ $doc->{_source}{tags} = [ delete $doc->{_source}{tag} ];
+ return $doc
+ }
+ );
+
+=head1 TODO
+
+=over
=item *
View
@@ -32,6 +32,7 @@ sub reindex {
my $bulk_size = $args{bulk_size} || $size;
my $dest_index = $self->name;
my $model = $self->model;
+ my $transform = $args{transform} || sub {@_};
printf "Reindexing domain ($domain) to index ($dest_index)\n" if $verbose;
@@ -47,7 +48,7 @@ sub reindex {
# later, when they're used in docs that aren't being reindexed
my @uids;
my $doc_updater = sub {
- my ($doc) = @_;
+ my ($doc) = $transform->(@_);
push @uids, [ @{$doc}{qw(_index _type _id)} ];
$doc->{_index} = $dest_index;
return $doc;
@@ -266,6 +267,8 @@ L<namespace|Elastic::Model::Namespace>, pass in a list of C<@types>.
scan => '2m',
quiet => 0,
+ transform => sub {...},
+
on_conflict => sub {...} | 'IGNORE'
on_error => sub {...} | 'IGNORE'
uid_on_conflict => sub {...} | 'IGNORE'
@@ -314,6 +317,22 @@ If true (the default), L</repoint_uids()> will be called automatically to
update any L<UIDs|Elastic::Model::UID> (which point at the old index) in
indices other than the ones currently being reindexed.
+=item transform
+
+If you need to change the structure/data of your doc while reindexing, you
+can pass a C<transform> coderef. This will be called before any changes
+have been made to the doc, and should return the new doc. For instance,
+to convert the single-value C<tag> field to an array of C<tags>:
+
+ $index->reindex(
+ 'new_index',
+ 'transform' => sub {
+ my $doc = shift;
+ $doc->{_source}{tags} = [ delete $doc->{_source}{tag} ];
+ return $doc
+ }
+ );
+
=item on_conflict / on_error
If you are indexing to the new index at the same time as you are reindexing,
View
@@ -4,7 +4,6 @@ use strict;
use warnings;
use Test::More 0.96;
use Test::Exception;
-use Scalar::Util qw(refaddr weaken);
use Test::Deep;
use ElasticSearch;
@@ -4,7 +4,6 @@ use strict;
use warnings;
use Test::More 0.96;
use Test::Exception;
-use Scalar::Util qw(refaddr weaken);
use Test::Deep;
use ElasticSearch;
@@ -0,0 +1,44 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Test::More 0.96;
+use Test::Exception;
+use Test::Deep;
+use ElasticSearch;
+
+use lib 't/lib';
+
+our $es;
+do 'es.pl';
+
+use_ok 'MyApp' || print 'Bail out';
+
+my $model = new_ok( 'MyApp', [ es => $es ], 'Model' );
+ok my $ns = $model->namespace('myapp'), 'Got ns';
+
+my @users = create_users($model);
+
+# Reindex, transforming timestamp
+isa_ok my $new = $ns->index('myapp4'), 'Elastic::Model::Index', 'New index';
+
+ok $new->reindex(
+ 'myapp',
+ transform => sub {
+ my $doc = shift;
+ $doc->{_source}{timestamp} += 1000;
+ return $doc;
+ },
+ ),
+ 'Reindexed myapp to myapp4';
+$new->refresh;
+
+my $view = $model->view->facets(
+ timestamp => { statistical => { field => 'timestamp' } } )->size(0);
+my $old_facet = $view->domain('myapp')->search->facet('timestamp');
+my $new_facet = $view->domain('myapp4')->search->facet('timestamp');
+
+is $new_facet->{min}, $old_facet->{min} + 1000, 'Min timestamp changed';
+is $new_facet->{max}, $old_facet->{max} + 1000, 'Max timestamp changed';
+
+done_testing;

0 comments on commit 2829d6b

Please sign in to comment.