| DBIx-Class-Indexer-WebService-Solr documentation | Contained in the DBIx-Class-Indexer-WebService-Solr distribution. |
DBIx::Class::Indexer::WebService::Solr - Automatic indexing of DBIx::Class objects via WebService::Solr
package MySchema::Foo;
use base qw( DBIx::Class );
__PACKAGE__->load_components( qw( Indexed Core ) );
__PACKAGE__->table('foo');
__PACKAGE__->set_indexer('WebService::Solr');
__PACKAGE__->add_columns(
foo_id => { # automatically indexed as "id"
data_type => 'integer',
is_auto_increment => 1
},
name => {
data_type => 'varchar',
size => 10,
indexed => {
boost => '2.0',
}
},
location => {
data_type => 'varchar',
size => 50,
indexed => 1
}
);
__PACKAGE__->has_many( widgets => 'widget' );
__PACKAGE__->add_index_fields(
widget => {
source => 'widgets.name'
},
);
Connects a DBIx::Class-based class to a Solr index.
Creates a new WebSevice::Solr object and normalizes the fields to be indexed.
Normalizes the index fields so they all have hashref members with an optional boost key.
Uses the indexed fields information to determine how to get
the values for $key out of $object.
Constructs a new WebService::Solr::Document object, populates it with
data from $object, and returns it.
Calls update_or_create_document.
Calls update_or_create_document.
Deletes document from the index.
Will either update or add a document to the index.
Brian Cassidy <bricas@cpan.org>
Copyright 2008-2009 by Brian Cassidy
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
| DBIx-Class-Indexer-WebService-Solr documentation | Contained in the DBIx-Class-Indexer-WebService-Solr distribution. |
package DBIx::Class::Indexer::WebService::Solr; use strict; use warnings; our $VERSION = '0.02'; use base qw( DBIx::Class::Indexer DBIx::Class ); use WebService::Solr; use Scalar::Util (); __PACKAGE__->mk_classdata( _obj => undef ); __PACKAGE__->mk_classdata( _field_prep => {} );
sub new { my $class = shift; my $connect_info = shift; my $source = shift; my $self = bless { }, $class; $self->setup_fields( $source ); my $server = $connect_info->{ server }; my $opts = $connect_info->{ options } || {}; $opts->{ autocommit } = 1; my $solr = WebService::Solr->new( $server, $opts ); $self->_obj( $solr ); return $self; }
sub setup_fields { my( $self, $source ) = @_; return if $self->_field_prep->{ $source }; my $fields = $source->index_fields; # normalize field defs for my $key ( keys %$fields ) { $fields->{ $key } = { } if !ref $fields->{ $key }; } if( !exists $fields->{ id } ) { $fields->{ id } = { }; } $self->_field_prep->{ $source } = 1; }
sub value_for_field { my( $self, $object, $key ) = @_; my $info = $object->index_fields->{ $key }; my $source = $info->{ source } || $key; if( ref $source eq 'CODE' ) { return $source->( $object ); } elsif( not ref $source ) { my @accessors = split /\./, $source; # no use calling 'me' on myself... shift @accessors if lc $accessors[ 0 ] eq 'me'; # traverse accessors my @values = $object; for my $accessor ( @accessors ) { @values = grep { defined } map { Scalar::Util::blessed( $_ ) and $_->can( $accessor ) ? $_->$accessor : ref $_ eq 'HASH' ? $_->{ $accessor } : undef } @values; } return wantarray ? @values : $values[ 0 ]; } }
sub as_document { my( $self, $object ) = @_; my $document = WebService::Solr::Document->new; # this is basically a no-op if it's already been done # but it needs to be done in case the same indexer is # used for multiple sources $self->setup_fields( ref $object ); my $fields = $object->index_fields; # for each field... for my $name ( keys %$fields ) { my $opts = $fields->{$name}; my @values = $self->value_for_field( $object, $name ); for( @values ) { $document->add_fields( [ $name => $_, $opts ] ); } } return $document; }
sub insert { my $self = shift; my $object = shift; $self->update_or_create_document( $object ); }
sub update { my $self = shift; my $object = shift; $self->update_or_create_document( $object ); }
sub delete { my $self = shift; my $object = shift; my $solr = $self->_obj; $self->setup_fields( ref $object ); my $id = $self->value_for_field( $object, 'id' ); $solr->delete_by_id( $id ); }
sub update_or_create_document { my $self = shift; my $object = shift; my $solr = $self->_obj; $self->setup_fields( ref $object ); # add == update $solr->add( $self->as_document( $object ) ); }
1;