Catmandu-Store-OpenSearch

 view release on metacpan or  search on metacpan

lib/Catmandu/Store/OpenSearch/CQL.pm  view on Meta::CPAN

        $query->{match_all} = {};
        return $query;
    }

    my $qualifier = $node->getQualifier;
    my $relation  = $node->getRelation;
    my @modifiers = $relation->getModifiers;
    my $base      = lc $relation->getBase;

    if ($base eq 'scr') {
        if ($self->mapping and my $rel = $self->mapping->{default_relation}) {
            $base = $rel;
        }
        else {
            $base = '=';
        }
    }

    if ($qualifier =~ $RE_ANY_FIELD) {
        if ($self->mapping and my $idx = $self->mapping->{default_index}) {
            $qualifier = $idx;
        }
        else {
            $qualifier = '_all';
        }
    }

    my $nested;

    if ($self->mapping and my $indexes = $self->mapping->{indexes}) {
        $qualifier = lc $qualifier;
        $qualifier =~ s/(?<=[^_])_(?=[^_])//go
            if $self->mapping->{strip_separating_underscores};
        my $mapping = $indexes->{$qualifier}
            or Catmandu::Error->throw("cql error: unknown index $qualifier");
        $mapping->{op}{$base}
            or
            Catmandu::Error->throw("cql error: relation $base not allowed");
        my $op = $mapping->{op}{$base};
        if (ref $op && $op->{field}) {
            $qualifier = $op->{field};
        }
        elsif ($mapping->{field}) {
            $qualifier = $mapping->{field};
        }

        my $filters;
        if (ref $op && $op->{filter}) {
            $filters = $op->{filter};
        }
        elsif ($mapping->{filter}) {
            $filters = $mapping->{filter};
        }
        if ($filters) {
            for my $filter (@$filters) {
                if ($filter eq 'lowercase') {$term = lc $term;}
            }
        }
        if (ref $op && $op->{cb}) {
            my ($pkg, $sub) = @{$op->{cb}};
            $term = require_package($pkg)->$sub($term);
        }
        elsif ($mapping->{cb}) {
            my ($pkg, $sub) = @{$mapping->{cb}};
            $term = require_package($pkg)->$sub($term);
        }

        $nested = $mapping->{nested};
    }

    # TODO just pass query around
    my $es_node = $self->_term_node($base, $qualifier, $term, @modifiers);

    if ($nested) {
        if ($nested->{query}) {
            $es_node = {bool => {must => [$nested->{query}, $es_node,]}};
        }
        $es_node = {nested => {path => $nested->{path}, query => $es_node,}};
    }

    for my $key (keys %$es_node) {
        $query->{$key} = $es_node->{$key};
    }

    $query;
}

sub _parse_prox_node ($self, $node, $query) {
    my $slop      = 0;
    my $qualifier = $node->left->getQualifier;
    my $term      = join(' ', $node->left->getTerm, $node->right->getTerm);
    if (my ($n) = $node->op =~ $RE_DISTANCE_MODIFIER) {
        $slop = $n - 1 if $n > 1;
    }
    if ($qualifier =~ $RE_ANY_FIELD) {
        if ($self->mapping and my $idx = $self->mapping->{default_index}) {
            $qualifier = $idx;
        }
        else {
            $qualifier = '_all';
        }
    }
    
    $query->{match_phrase} = {$qualifier => {query => $term, slop => $slop}};
}

sub _term_node ($self, $base, $qualifier, $term, @modifiers) {
    my $q;
    if ($base eq '=') {
        if (ref $qualifier) {
            return {
                bool => {
                    should => [
                        map {
                            if ($_ eq $self->id_key) {
                                {ids => {values => [$term]}};
                            }
                            else {
                                $self->_text_node($_, $term, @modifiers);
                            }
                        } @$qualifier
                    ]
                }
            };
        }



( run in 3.030 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )