2017 © Pedro Peláez
 

library elastic-query

PHP query builder for ElasticSearch with fluent interface

image

bardex/elastic-query

PHP query builder for ElasticSearch with fluent interface

  • Friday, September 15, 2017
  • by bardex
  • Repository
  • 3 Watchers
  • 1 Stars
  • 342 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 1 Forks
  • 1 Open issues
  • 15 Versions
  • 0 % Grown

The README.md

PHP fluent interface for ElasticSearch

Build Status Scrutinizer Code Quality Coverage Status, (*1)

REQUIREMENTS

  • PHP >= 5.5
  • PHP Elasticsearch\Client ~2.0 or ~5.0 (only PHP >= 5.6.6)
  • ElasticSearch server >= 5.0

INSTALLATION

$ composer require bardex/elastic-query

QUICK START

setHosts(['localhost'])
           ->build();

$query = new \Bardex\Elastic\SearchQuery($elastic);

$query->setIndex('products')
  ->setType('products')
  ->where('rubric')->in([1,5,7])
  ->where('price')->greater(0)
  ->where(['title','anons'])->match('game')
  ->exclude(['anons', 'comments']) // exclude fields
  ->setOrderBy('rating', 'desc')
  ->addOrderBy('dateCreation', 'desc')
  ->limit(30, 0);

// this is instance of \Bardex\Elastic\SearchResult
$results = $query->fetchAll();

// count of fetched results
$countResults = count($results);

// count of total found results
$totalFound = $results->getTotalFound();

// iterate results
foreach ($results as $result) {
    echo $result['id'] . ':' . $result['title'] . '
'; } // get first result (or null if empty) $first = $results->getFirst(); // nothing found ? $results->isEmpty(); ?>

USING MULTI-QUERY

You can use MultiQuery to execute multiple search queries for one request to the server. https://www.elastic.co/guide/en/elasticsearch/reference/current/search-multi-search.html, (*2)

setHosts(['localhost'])
           ->build();

$posts = new \Bardex\Elastic\SearchQuery($elastic);
$posts->setIndex('posts')
  ->setType('posts')
  ->where('userId')->equal(1)
  ->where('status')->equal('published')
  ->setOrderBy('dateCreation', 'desc')
  ->limit(10, 0);

$user = new \Bardex\Elastic\SearchQuery($elastic);
$user->setIndex('users')
  ->setType('users')
  ->where('id')->equal(1);

$multi = new \Bardex\Elastic\MultiQuery($elastic);
$multi->addQuery('user', $user);
$multi->addQuery('posts', $posts);
// instance of \Bardex\Elastic\SearchQuery
$result = $multi->fetchAll();

// instance of \Bardex\Elastic\SearchQuery
$user  = $result['user'];
$posts = $result['posts'];
$totalPosts = $posts->getTotalFound();
?>

USING LISTENER FOR LOGGING

setHosts(['localhost'])
           ->build();

$logger = new Logger; // some logger implemented \Psr\Log\LoggerInterface, like Monolog.
$logger->setFacility('elastic-query');
$listener = new \Bardex\Elastic\Listener\Logger($logger);
$listener->setLogAllQueries(true);   // debug log-level
$listener->setLogErrorQueries(true); // error log-level
$listener->setLogSlowQueries(true);  // warning log-level
$listener->setSlowQueryLimitMs(100);

$query = new \Bardex\Elastic\SearchQuery($elastic);
$query->addListener($listener);

$query->setIndex('products')
  ->setType('products')
  ->where('rubric')->in([1,5,7])
  ->where('price')->greater(0)
  ->addOrderBy('dateCreation', 'desc')
  ->limit(30, 0);

$query->fetchAll();
?>

USING PROTOTYPE FOR CREATION QUERY OBJECTS

You can use one or more pre-configured prototypes for creating queries., (*3)

setHosts(['localhost'])
           ->build();

$prototype = new \Bardex\Elastic\PrototypeQuery($elastic);

$logger = new Logger; // some logger implemented \Psr\Log\LoggerInterface, like Monolog.
$logger->setFacility('elastic-query');

$listener = new \Bardex\Elastic\Listener\Logger($logger);
$listener->setLogAllQueries(true);   // debug log-level
$listener->setLogErrorQueries(true); // error log-level
$listener->setLogSlowQueries(true);  // warning log-level
$listener->setSlowQueryLimitMs(100);
$prototype->addListener($listener);

$user = $prototype->createSearchQuery()
    ->setIndex('users')
    ->setType('users')
    ->where('id')->equal(1);

$posts = $prototype->createSearchQuery()
    ->setIndex('posts')
    ->setType('posts')
    ->where('user_id')->equal(1);


$multiQuery  = $prototype->createMultiQuery();
$multiQuery->addQuery('user', $user);
$multiQuery->addQuery('posts', $posts);
$results = $multiQuery->fetchAll();        

?>
<?php
class UserElasticRepository 
{
   /**
    * @var \Bardex\Elastic\PrototypeQuery  
    */
    protected $elastic;

    public function __construct(\Bardex\Elastic\PrototypeQuery $elastic) 
    {
        $this->elastic = $elastic;    
    }

    public function findById($id)
    {
        return $this->elastic->createSearchQuery()
                             ->setIndex('users')
                             ->setType('users')
                             ->where('id')->equal($id)
                             ->limit(1)
                             ->fetchAll()
                             ->getFirst();
    }
}
?>

AVAILABLE FILTERING METHODS (in SearchQuery)

  • equal($value)
  • in([$v1,$v2,...])
  • less($max)
  • lessOrEqual($max)
  • greater($min)
  • greaterOrEqual($min)
  • between($min, $max), (*4)

  • match($text) - full-text search, (*5)

  • wildcard('rosy*')
  • regexp('ro.*n'), (*6)

  • less($dateEnd, $dateFormat), (*7)

  • lessOrEqual($dateEnd, $dateFormat)
  • greater($dateStart, $dateFormat)
  • greaterOrEqual($dateStart, $dateFormat)
  • between($start, $end, $dateFormat), (*8)

  • exists() - field exists and not empty, (*9)

  • not($value) - not equal, (*10)

  • notIn([$v1,$v2,...])
  • notBetween($min, $max)
  • notMatch($text) - text not match
  • notExists() - field not exists or empty

Also see class \Bardex\Elastic\Where.
Date format see https://www.elastic.co/guide/en/elasticsearch/reference/5.0/mapping-date-format.html
Exists filter https://www.elastic.co/guide/en/elasticsearch/reference/5.0/query-dsl-exists-query.html, (*11)

Examples, (*12)

<?php
$query->where('id')->equal(10)
        ->where('category')->in([1,5,3])
        ->where(['title','anons'])->match('game') // full-text search by multi fields
        ->where('price')->between(100,1000) // min and max values included
        ->where('date_creation')->greater('2017-01-31T23:00:00+03:00', 'date_time_no_millis')
        ->where('refunds')->notExists();
?>

FETCH SPECIFIED FIELDS

Methods select() and exclude() can be used together., (*13)

<?php
    $query->select(['id', 'title', 'comments.*', 'categories.*'])
          ->exclude(['description', '*.description']);
?>

LIMIT FETCH DOCUMENTS

<?php
    $query->limit($limit, $offset);
?>

SORT DOCUMENTS

<?php
    $query->setOrderBy('date_creation', 'desc'); // clear old order and set new order
    $query->addOrderBy('rating', 'desc'); // add order
?>

USING SCRIPT-FIELDS

Also see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-script-fields.html
Method searchQuery::fetchAll() merge script fields with fields of documents., (*14)

addLine('def a = 100;');
    $script->addLine('return a;'); // return scalar

    $query->addScriptField('fieldName', $script);
    $result = $query->fetchAll()->getFirst();
    echo $result['fieldName']; // 100
    
    // script return array
    $script = new \Bardex\Elastic\Script();
    $script->addLine('def a = 100;');
    $script->addLine('def b = 200;');
    $script->addLine('return [a,b];'); // return array
    
    $query->addScriptField('fieldName', $script);
    $result = $query->fetchAll()->getFirst();
    print_r($result['fieldName']); // [100, 200]
?>

Use documents values and script params.
Also see:
https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-expression.html, (*15)

addLine("return  doc['id'].value * params.power;");
    $script->addParam('power', 1000);
    $query->addScriptField('pid', $script);
    $row = $query->fetchAll()->getFirst();
    echo $row['id']; // 2
    echo $row['pid']; // 2000
?>

USING SCRIPT-FILTERS

Also see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-script-query.html, (*16)

addLine("return doc['price'].value * (1 + doc['tax'].value / 100) addParam('max_price', 10000);
    $query->whereScript($script);
    $rows = $query->fetchAll();
?>

DEBUGGING

Get prepared elastic query as php-array:, (*17)

<?php
    $query->getQuery();
?>

Get raw response from ElasticSearch server:, (*18)

<?php
    $query->fetchRaw();
?>

The Versions

15/09 2017

v3.x-dev

3.9999999.9999999.9999999-dev

PHP query builder for ElasticSearch with fluent interface

  Sources   Download

The Requires

 

The Development Requires

by Andrey Volynov
by Alexey Sumin

13/09 2017

dev-feature/multi_query

dev-feature/multi_query

PHP query builder for ElasticSearch with fluent interface

  Sources   Download

The Requires

 

The Development Requires

by Andrey Volynov
by Alexey Sumin

13/09 2017

v2.x-dev

2.9999999.9999999.9999999-dev

PHP query builder for ElasticSearch with fluent interface

  Sources   Download

The Requires

 

The Development Requires

by Andrey Volynov
by Alexey Sumin

13/09 2017

2.1.0

2.1.0.0

PHP query builder for ElasticSearch with fluent interface

  Sources   Download

The Requires

 

The Development Requires

by Andrey Volynov
by Alexey Sumin

10/09 2017

2.0.0

2.0.0.0

PHP query builder for ElasticSearch with fluent interface

  Sources   Download

The Requires

 

The Development Requires

by Andrey Volynov
by Alexey Sumin

12/08 2017

dev-master

9999999-dev

PHP query builder for ElasticSearch with fluent interface

  Sources   Download

The Requires

 

The Development Requires

by Andrey Volynov
by Alexey Sumin

12/08 2017

dev-devel

dev-devel

PHP query builder for ElasticSearch with fluent interface

  Sources   Download

The Requires

 

The Development Requires

by Andrey Volynov
by Alexey Sumin

12/08 2017

1.1.3

1.1.3.0

PHP query builder for ElasticSearch with fluent interface

  Sources   Download

The Requires

 

The Development Requires

by Andrey Volynov
by Alexey Sumin

14/06 2017

1.1.2

1.1.2.0

PHP query builder for ElasticSearch with fluent interface

  Sources   Download

The Requires

 

The Development Requires

by Andrey Volynov
by Alexey Sumin

12/06 2017

1.1.1

1.1.1.0

  Sources   Download

The Requires

 

The Development Requires

by Alexey Sumin

11/06 2017

1.1

1.1.0.0

  Sources   Download

The Requires

 

The Development Requires

by Alexey Sumin

09/06 2017

1.0

1.0.0.0

  Sources   Download

The Requires

 

The Development Requires

by Alexey Sumin

04/05 2017

0.1.2

0.1.2.0

  Sources   Download

The Requires

 

The Development Requires

by Alexey Sumin

04/05 2017

0.1.1

0.1.1.0

  Sources   Download

The Requires

 

The Development Requires

by Alexey Sumin

27/04 2017

0.1

0.1.0.0

  Sources   Download

The Requires

 

The Development Requires

by Alexey Sumin