bardex/elastic-query 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

bardex/elastic-query

Composer 安装命令:

composer require bardex/elastic-query

包简介

PHP query builder for ElasticSearch with fluent interface

README 文档

README

Build Status Scrutinizer Code Quality Coverage Status

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

<?php
use Bardex\Elastic\Client;

// 1. Create client: 
$client = Client::create('localhost');

// OR
$elastic = \Elasticsearch\ClientBuilder::create()
           ->setHosts(['localhost'])
           ->build();

$client = new Client($elastic);

// 2. Create search query
// this is instance of \Bardex\Elastic\SearchQuery
$query = $client->createSearchQuery(); 

$query->setIndex('shop', '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'] . '<br>';
}

//Fetch one column as array
$result->fetchColumn('id'); // ex. return [1,2,3] or []

// 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

<?php
use Bardex\Elastic\Client;

$client = Client::create('localhost');

$postsQuery = $client->createSearchQuery()
    ->setIndex('blog', 'posts')
    ->where('userId')->equal(1)
    ->where('status')->equal('published')
    ->setOrderBy('dateCreation', 'desc')
    ->limit(10, 0);

$userQuery = $client->createSearchQuery()
    ->setIndex('blog', 'users')
    ->where('id')->equal(1);

$results = $client->createMultiQuery()
    ->addQuery('posts', $postsQuery)
    ->addQuery('user', $userQuery)
    ->fetchAll();

$user  = $results['user'];
$posts = $results['posts'];
$totalPosts = $posts->getTotalFound();

// OR

$multi = $client->createMultiQuery();

$multi->createSearchQuery('posts')
    ->setIndex('blog', 'posts')
    ->where('userId')->equal(1)
    ->where('status')->equal('published')
    ->setOrderBy('dateCreation', 'desc')
    ->limit(10, 0);

$multi->createSearchQuery('user')
    ->setIndex('blog', 'users')
    ->where('id')->equal(1);
    
$results = $multi->fetchAll();
$user  = $results['user'];
$posts = $results['posts'];
?>

USING LISTENER FOR LOGGING

<?php
use Bardex\Elastic\Client;


$client = Client::create('localhost');

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

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

$client->addListener($log);

?>

USE OF A CUSTOM HYDRATOR

<?php
use Bardex\Elastic\Client;

$client = Client::create('localhost');

// hydrator must implements interface \Bardex\Elastic\IHydrator or extends \Bardex\Elastic\Hydrator
$hydrator = new CustomHydrator;
$client->setHydrator($hydrator);

?>

AVAILABLE FILTERING METHODS (in SearchQuery)

  • equal($value)

  • in([$v1,$v2,...])

  • less($max)

  • lessOrEqual($max)

  • greater($min)

  • greaterOrEqual($min)

  • between($min, $max)

  • match($text, $operator = 'or') - full-text search

  • wildcard('rosy*')

  • regexp('ro.*n')

  • less($dateEnd, $dateFormat)

  • lessOrEqual($dateEnd, $dateFormat)

  • greater($dateStart, $dateFormat)

  • greaterOrEqual($dateStart, $dateFormat)

  • between($start, $end, $dateFormat)

  • exists() - field exists and not empty

  • not($value) - not equal

  • notIn([$v1,$v2,...])

  • notBetween($min, $max)

  • notMatch($text) - text not match

  • notExists() - field not exists or empty

  • minScore() - filtered by min score

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

Examples

<?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()
        ->minScore(0.1);
?>

SEARCH CONTEXT

A query that matches documents matching boolean combinations of other queries. It is built using one or more boolean clauses, each clause with a typed occurrence. The occurrence types are:

  • must - The clause (query) must appear in matching documents and will contribute to the score.
  • filter - The clause (query) must appear in matching documents. However unlike must the score of the query will be ignored. Filter clauses are executed in filter context, meaning that scoring is ignored and clauses are considered for caching.
  • should - The clause (query) should appear in the matching document. If the bool query is in a query context and has a must or filter clause then a document will match the bool query even if none of the should queries match. In this case these clauses are only used to influence the score. If the bool query is a filter context or has neither must or filter then at least one of the should queries must match a document for it to match the bool query.

By default used must context.

Also see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html

Examples

<?php
use Bardex\Elastic\Query;

$query->where('id')->equal(10)
       ->where('category', Query::CONTEXT_FILTER)->equal(1)
       ->where('status', Query::CONTEXT_FILTER)->equal('published')
       ->where('title', Query::CONTEXT_SHOULD)->match('game') 
       ->where('tags', Query::CONTEXT_SHOULD)->in(['game', 'gamebox']) 
       ->setOrderBy(Query::ORDER_BY_SCORE, 'desc');
         
?>

FETCH SPECIFIED FIELDS

Methods select() and exclude() can be used together.

<?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.

<?php 
    // script return scalar
    $script = new \Bardex\Elastic\Script();
    $script->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

<?php
    $script = new Script();
    $script->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

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

DEBUGGING

Get prepared elastic query as php-array:

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

Get raw response from ElasticSearch server:

<?php
    $query->fetchAll(false);
?>

bardex/elastic-query 适用场景与选型建议

bardex/elastic-query 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 353 次下载、GitHub Stars 达 1, 最近一次更新时间为 2017 年 05 月 04 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 bardex/elastic-query 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 bardex/elastic-query 我们能提供哪些服务?
定制开发 / 二次开发

基于 bardex/elastic-query 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 353
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 3
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: Unknown
  • 更新时间: 2017-05-04