<commit_before><?php

namespace RulerZ\Compiler\Target\Elasticsearch;

use Hoa\Ruler\Model as AST;

use RulerZ\Compiler\Target\GenericVisitor;
use RulerZ\Model;

/**
 * Base class for Elasticsearch-related visitors.
 */
abstract class GenericElasticsearchVisitor extends GenericVisitor
{
    /**
     * @inheritDoc
     */
    public function visitAccess(AST\Bag\Context $element, &$handle = null, $eldnah = null)
    {
        $dimensions = $element->getDimensions();

        // nested path
        if (!empty($dimensions)) {
            return $this->flattenAccessPath($element);
        }

        return $element->getId();
    }

    /**
     * {@inheritDoc}
     */
    public function visitParameter(Model\Parameter $element, &$handle = null, $eldnah = null)
    {
        return sprintf('$parameters["%s"]', $element->getName());
    }

    /**
     * {@inheritDoc}
     */
    public function visitScalar(AST\Bag\Scalar $element, &$handle = null, $eldnah = null)
    {
        $value = parent::visitScalar($element, $handle, $eldnah);

        return is_numeric($value) ? $value : sprintf("'%s'", $value);
    }

    /**
     * {@inheritDoc}
     */
    public function visitArray(AST\Bag\RulerArray $element, &$handle = null, $eldnah = null)
    {
        $array = parent::visitArray($element, $handle, $eldnah);

        return sprintf('[%s]', implode(', ', $array));
    }

    /**
     * @inheritDoc
     */
    protected function defineBuiltInOperators()
    {
        // start with a few helpers
        $must = function($query) {
            return "[
    'bool' => ['must' => $query]
]";
        };
        $mustNot = function($query) {
            return "[
                'bool' => ['must_not' => $query]
            ]";
        };
        $range = function($field, $value, $operator) use ($must) {
            return $must("[
                'range' => [
                    '$field' => ['$operator' => $value],
                ]
            ]");
        };

        // Here are the operators!
        $this->setInlineOperator('and', function ($a, $b) use ($must) {
            return $must("[$a, $b]");
        });
        $this->setInlineOperator('or', function ($a, $b) use ($must) {
            return "[
                'bool' => ['should' => [$a, $b], 'minimum_should_match' => 1]
            ]";
        });

        $this->setInlineOperator('like', function ($a, $b) use ($must) {
            $value = is_array($b) ? implode(' ', $b) : $b;

            return $must("[
                'match' => [
                    '$a' => '$value',
                ]
            ]");
        });
        $this->setInlineOperator('has', function ($a, $b) use ($must) {
            $value = is_array($b) ? '[' . implode(', ', $b) . ']' : $b;

            return $must("[
                'terms' => [
                    '$a' => $value,
                ]
            ]");
        });
        $this->setInlineOperator('in', $this->getInlineOperator('has'));

        $this->setInlineOperator('=', function ($a, $b) use ($must) {
            return $must("[
                'term' => [
                    '$a' => $b,
                ]
            ]");
        });

        $this->setInlineOperator('!=', function ($a, $b) use ($mustNot) {
            return $mustNot("[
                'term' => [
                    '$a' => $b,
                ]
            ]");
        });

        $this->setInlineOperator('not', $mustNot);

        $this->setInlineOperator('match_all', function() {
            return "['match_all' => []]";
        });

        $this->setInlineOperator('>', function ($a, $b) use ($range) {
            return $range($a, $b, 'gt');
        });

        $this->setInlineOperator('>=', function ($a, $b) use ($range) {
            return $range($a, $b, 'gte');
        });

        $this->setInlineOperator('<', function ($a, $b) use ($range) {
            return $range($a, $b, 'lt');
        });

        $this->setInlineOperator('<=', function ($a, $b) use ($range) {
            return $range($a, $b, 'lte');
        });

        $this->setInlineOperator('in_envelope', function ($a, $b) use ($must) {
            return $must([
                'geo_shape' => [
                    $a => [
                        'shape' => [
                            'type'        => 'envelope',
                            'coordinates' => $b,
                        ]
                    ]
                ]
            ]);
        });
    }

    /**
     * @param AST\Bag\Context $element Element to visit.
     *
     * @return string
     */
    private function flattenAccessPath(AST\Bag\Context $element)
    {
        $flattenedDimensions = [$element->getId()];
        foreach ($element->getDimensions() as $dimension) {
            $flattenedDimensions[] = $dimension[1];
        }

        return implode('.', $flattenedDimensions);
    }
}<commit_msg>Remove in_enveloppe and match_all operators for elasticsearch<commit_after><?php

namespace RulerZ\Compiler\Target\Elasticsearch;

use Hoa\Ruler\Model as AST;

use RulerZ\Compiler\Target\GenericVisitor;
use RulerZ\Model;

/**
 * Base class for Elasticsearch-related visitors.
 */
abstract class GenericElasticsearchVisitor extends GenericVisitor
{
    /**
     * @inheritDoc
     */
    public function visitAccess(AST\Bag\Context $element, &$handle = null, $eldnah = null)
    {
        $dimensions = $element->getDimensions();

        // nested path
        if (!empty($dimensions)) {
            return $this->flattenAccessPath($element);
        }

        return $element->getId();
    }

    /**
     * {@inheritDoc}
     */
    public function visitParameter(Model\Parameter $element, &$handle = null, $eldnah = null)
    {
        return sprintf('$parameters["%s"]', $element->getName());
    }

    /**
     * {@inheritDoc}
     */
    public function visitScalar(AST\Bag\Scalar $element, &$handle = null, $eldnah = null)
    {
        $value = parent::visitScalar($element, $handle, $eldnah);

        return is_numeric($value) ? $value : sprintf("'%s'", $value);
    }

    /**
     * {@inheritDoc}
     */
    public function visitArray(AST\Bag\RulerArray $element, &$handle = null, $eldnah = null)
    {
        $array = parent::visitArray($element, $handle, $eldnah);

        return sprintf('[%s]', implode(', ', $array));
    }

    /**
     * @inheritDoc
     */
    protected function defineBuiltInOperators()
    {
        // start with a few helpers
        $must = function($query) {
            return "[
    'bool' => ['must' => $query]
]";
        };
        $mustNot = function($query) {
            return "[
                'bool' => ['must_not' => $query]
            ]";
        };
        $range = function($field, $value, $operator) use ($must) {
            return $must("[
                'range' => [
                    '$field' => ['$operator' => $value],
                ]
            ]");
        };

        // Here are the operators!
        $this->setInlineOperator('and', function ($a, $b) use ($must) {
            return $must("[$a, $b]");
        });
        $this->setInlineOperator('or', function ($a, $b) use ($must) {
            return "[
                'bool' => ['should' => [$a, $b], 'minimum_should_match' => 1]
            ]";
        });

        $this->setInlineOperator('like', function ($a, $b) use ($must) {
            $value = is_array($b) ? implode(' ', $b) : $b;

            return $must("[
                'match' => [
                    '$a' => '$value',
                ]
            ]");
        });
        $this->setInlineOperator('has', function ($a, $b) use ($must) {
            $value = is_array($b) ? '[' . implode(', ', $b) . ']' : $b;

            return $must("[
                'terms' => [
                    '$a' => $value,
                ]
            ]");
        });
        $this->setInlineOperator('in', $this->getInlineOperator('has'));

        $this->setInlineOperator('=', function ($a, $b) use ($must) {
            return $must("[
                'term' => [
                    '$a' => $b,
                ]
            ]");
        });

        $this->setInlineOperator('!=', function ($a, $b) use ($mustNot) {
            return $mustNot("[
                'term' => [
                    '$a' => $b,
                ]
            ]");
        });

        $this->setInlineOperator('not', $mustNot);

        $this->setInlineOperator('>', function ($a, $b) use ($range) {
            return $range($a, $b, 'gt');
        });

        $this->setInlineOperator('>=', function ($a, $b) use ($range) {
            return $range($a, $b, 'gte');
        });

        $this->setInlineOperator('<', function ($a, $b) use ($range) {
            return $range($a, $b, 'lt');
        });

        $this->setInlineOperator('<=', function ($a, $b) use ($range) {
            return $range($a, $b, 'lte');
        });
    }

    /**
     * @param AST\Bag\Context $element Element to visit.
     *
     * @return string
     */
    private function flattenAccessPath(AST\Bag\Context $element)
    {
        $flattenedDimensions = [$element->getId()];
        foreach ($element->getDimensions() as $dimension) {
            $flattenedDimensions[] = $dimension[1];
        }

        return implode('.', $flattenedDimensions);
    }
}
{'fraction_non_alphanumeric': 0.18274602492479589, 'fraction_numerical': 0.0004297378599054577, 'mean_word_length': 1.660474421263218, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 89, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6743573', 'n_tokens_mistral': 2790, 'n_tokens_neox': 2741, 'n_words': 559}