Mojito

 view release on metacpan or  search on metacpan

lib/Mojito/Collection/CRUD/Elasticsearch.pm  view on Meta::CPAN

The motivation for collections of docs collection is so that we can group 
documents together form display purposes.  Form example, say I'm working 
on a project with multiple documents.  I'd like to be able to "identify/tag" 
them to the project so I can narrow my viewing focus to just those documents.

=cut

sub create {
    my ( $self, $params ) = @_;

    # We don't need to store the form submit value
    delete $params->{collect};
    my $page_ids = $params->{collected_page_ids};
    
    # NOTE: The $page_ids input can come in two different forms: 
    # - String:   "$page_id1,$page_id2,...$page_id_n";
    # - ArrayRef: [$page_id1,$page_id2,..., $page_id_n];
    $params->{collected_page_ids} = [split ',', $page_ids] if (!ref($page_ids));
    
    # add save time as last_modified and created
    $params->{last_modified} = $params->{created} = time();

    my $collection_struct = $self->collection->{hits}{hits};
    my @collections = map { $_->{_source} } @{$collection_struct};
    my $collection = first { $_->{collection_name} eq $params->{collection_name} } @collections;
    $params->{id} = 
         $collection->{_id} 
      || $collection->{id} 
      || $self->generate_mongo_like_oid;
    $self->db->index(
        index => $self->db_name,
        type  => $self->collection_name,
        id    => $params->{id}, 
        body  => $params,
    );
    return $params->{id};
}

=head2 read

Read a collection from the database.

=cut

sub read {
    my ( $self, $id ) = @_;
    my $doc = $self->db->get_source(
        index => $self->db_name,
        type => $self->collection_name,
        id => $id,
    );
    return $doc;
}

=head2 update

Update a collection in the database.

=cut

sub update {
    my ( $self, $id, $params) = @_;

    $params->{last_modified} = time();
    $self->db->update(
        index => $self->db_name,
        type  => $self->collection_name,
        id    => $id,
        body  =>  { doc => $params },
    );
}

=head2 delete

Delete a collection from the database.

=cut

sub delete {
    my ( $self, $id ) = @_;
    $self->collection->delete($id);
}

=head2 get_all

Get all pages in the notes collection.
Returns a MongoDB cursor one can iterate over.

=cut

sub get_all {
    my $self = shift;
    return $self->collection->{hits}{hits};
}

=head2 collection_for_page

Get all the collection ids for which this page is a member of.

=cut

sub collections_for_page {
    my ( $self, $page_id ) = @_;

    $page_id //= '';
    my @collection_ids = ();
    my @collections = map { $_->{_source} } @{$self->get_all};
    foreach my $collection (@collections) {
        if ($page_id eq any(@{$collection->{collected_page_ids}})) {
            push @collection_ids, $collection->{id};
        }
    }

    return @collection_ids;
}

sub update_collection_membership {
    my ($self, $params) = @_;

    my $collection_ids = $params->{collection_select};
     # Want to coerce (single select) SCALAR into an ArrayRef (happens w/ Dancer params)
    if (ref($collection_ids) ne 'ARRAY') {
        warn "Coercing collection select params into an ArrefRef" if $ENV{MOJITO_DEBUG};
        $collection_ids = [$collection_ids];
    }

    my $scroll = $self->db->scroll_helper(
        index => $self->db_name,
        type  => $self->collection_name,
        body => {query => {term => {collected_page_ids => $params->{mongo_id}}}},
    );
    my %HAVE;
    while (my $collection = $scroll->next) {
        $HAVE{$collection->{_source}{id}} = 1;
    }
    my %WANT = map { $_ => 1 } @{$collection_ids};
    foreach my $collection_id (keys %WANT) {
        if (not $HAVE{$collection_id}) {
        # add page_id to the collection
            my $collection = $self->read($collection_id);
            push @{$collection->{collected_page_ids}}, $params->{mongo_id};
            $self->update($collection_id, $collection);
        }
    }
    foreach my $collection_id (keys %HAVE) {
        if (not $WANT{$collection_id}) {
            # remove the page_id from the collection
            my $collection = $self->read($collection_id);
            my @collected_page_ids = grep { $_ ne $params->{mongo_id} }
              @{$collection->{collected_page_ids}};
            $self->update(
                $collection_id, 
                {collected_page_ids => \@collected_page_ids},
            );
        }
    }

    return;
}
=head2 BUILD

Set the collection we want to work with.
In this case it's the collection named 'collection'.
It's a bit meta is why the funny naming.

=cut

sub BUILD {
    my $self = shift;
    $self->collection_name('collection');
}

1



( run in 0.635 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )