PHP code example of jfxy / elasticsearch-query-builder

1. Go to this page and download the library: Download jfxy/elasticsearch-query-builder library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

jfxy / elasticsearch-query-builder example snippets


    public function select($fields) :self
    
    ->select('id','name')
    ->select(['id','name'])

    public function where($field, $operator = null, $value = null, $boolean = 'and', $not = false, $filter = false) :self
    public function orWhere($field, $operator = null, $value = null) :self
    public function whereNot($field, $value = null) :self
    public function orWhereNot($field, $value = null) :self
    
    ->where('id',1)
    ->where('id','=',1)
    ->where('id',[1,2])                         // 等同于  ->whereIn('id',[1,2])
    ->where('news_postdate','<=','2020-09-01')  // 等同于  ->whereBetween('news_postdate',['<=' => '2020-09-01'])
    
    // 闭包用法
    ->where(function($query){
        return $query->where('id',1)->orWhere('status','>',0);
    })
    ->orWhere(function($query){
        return $query->where('id',1)->orWhere('status','>',0);
    })
    
    // 数组用法,下面两种写法类似,数组用法下的time条件顺序跟直接传入where方法顺序一致即可
    ->where(['id' => 1,'status' => [0,1],['time','>=','2020-09-01']])
    ->where(function($query){
        $query->where('id',1)->where('status',[0,1])->where('time','>=','2020-09-01');
    })
    
    // whereNot实现 a != 1 and b != 2
    ->whereNot('a',1)->whereNot('b',2)
    
    // whereNot实现 a != 1 or b != 2,即not(a=1 and b=2)
    ->whereNot(['a'=>1,'b'=>2])
    ->whereNot(function($query){
        $query->where('a',1)->where('b',2);
    })

    public function filter($field, $operator = null, $value = null, $boolean = 'and',$not = false) :self
    public function orFilter($field, $operator = null, $value = null) :self
    public function filterNot($field, $value = null) :self
    public function orFilterNot($field, $value = null) :self

    public function whereIn($field, array $value, $boolean = 'and', $not = false) :self
    public function whereNotIn($field, array $value, $boolean = 'and') :self
    public function orWhereIn($field, array $value) :self
    public function orWhereNotIn($field, array $value) :self
    
    ->whereIn('id',[1,2])

    public function whereBetween($field, array $value, $boolean = 'and', $not = false) :self
    public function whereNotBetween($field, array $value, $boolean = 'and') :self
    public function orWhereBetween($field, array $value) :self
    public function orWhereNotBetween($field, array $value) :self
    
    ->whereBetween('id',[1,10])                     // 1 <= id <= 10
    ->whereBetween('id',[1,'<' => 10])              // 1 <= id < 10
    ->whereBetween('id',['>=' => 1,'<' => 10])      // 1 <= id < 10

    public function whereExists($field,$boolean = 'and', $not = false) :self
    public function whereNotExists($field) :self
    public function orWhereExists($field) :self
    public function orWhereNotExists($field) :self
    
    ->whereExists('news_uuid')

    public function wherePrefix($field, $value, $appendParams = [], $boolean = 'and', $not = false) :self
    public function whereNotPrefix($field, $value, $appendParams = []) :self
    public function orWherePrefix($field, $value, $appendParams = []) :self
    public function orWhereNotPrefix($field, $value, $appendParams = []) :self
    
    ->wherePrefix('news_url','http://www.baidu.com')

    public function whereWildcard($field, $value, $appendParams = [], $boolean = 'and', $not = false) :self
    public function whereNotWildcard($field, $value, $appendParams = []) :self
    public function orWhereWildcard($field, $value, $appendParams = []) :self
    public function orWhereNotWildcard($field, $value, $appendParams = []) :self
    
    ->whereWildcard('media_name','*公安')

    public function whereRegexp($field, $value, $appendParams = [], $boolean = 'and', $not = false) :self
    public function whereNotRegexp($field, $value, $appendParams = []) :self
    public function orWhereRegexp($field, $value, $appendParams = []) :self
    public function orWhereNotRegexp($field, $value, $appendParams = []) :self
    
    ->whereRegexp('media_name','.*公安')

    public function whereFuzzy($field, $value, $appendParams = [], $boolean = 'and', $not = false) :self
    public function whereNotFuzzy($field, $value, $appendParams = []) :self
    public function orWhereFuzzy($field, $value, $appendParams = []) :self
    public function orWhereNotFuzzy($field, $value, $appendParams = []) :self
    
    ->whereFuzzy('news_title','安徽合肥')

    public function whereRaw($where, $boolean = 'and', $not = false) :self
    public function orWhereRaw($where) :self
    
    // 下面的例子是由于where方法提供的term查询无法设置一些其他的参数,可以改为使用whereRaw
    ->whereRaw([
       "term" => [
           "news_title" => [
               "value" => "安徽",
               "boost" => 2
           ]
       ]
   ])
   
   ->whereRaw([
       'bool' => [
           'must' => [
               "term" => [
                   "news_title" => [
                       "value" => "安徽",
                       "boost" => 2
                   ]
               ]
           ]
       ]
   ])

    // 单字段
    public function whereMatch($field, $value = null,$type = 'match',array $appendParams = [], $boolean = 'and', $not = false) :self
    public function orWhereMatch($field, $value = null,$type = 'match',array $appendParams = []) :self
    public function whereNotMatch($field, $value = null,$type = 'match',array $appendParams = []) :self
    public function orWhereNotMatch($field, $value = null,$type = 'match',array $appendParams = []) :self
    // 多字段
    public function whereMultiMatch($field, $value = null,$type = 'best_fields',array $appendParams = [], $boolean = 'and', $not = false) :self
    public function orWhereMultiMatch($field, $value = null,$type = 'best_fields',array $appendParams = []) :self
    public function whereNotMultiMatch($field, $value = null,$type = 'best_fields',array $appendParams = []) :self
    public function orWhereNotMultiMatch($field, $value = null,$type = 'best_fields',array $appendParams = []) :self
    
    ->whereMatch('news_title','上海','match_phrase',['slop'=>1])
    ->whereMultiMatch(['news_title','news_content'],'上海','phrase',["operator" => "OR"])

    public function minimumShouldMatch($value) :self
    
    ->where('aa',1)->orWhere('bb',1)->orWhere('cc',1)->minimumShouldMatch(2)
    
    ->where(function(Es $query){
        $query->where('aa',1)->orWhere('bb',1)->orWhere('cc',1)
            ->minimumShouldMatch('50%');
    })
    
    ->postWhere(function(Es $query){
        $query->where('aa',1)->orWhere('bb',1)->orWhere('cc',1)
            ->minimumShouldMatch('50%');
    })

    public function whereNested($path,$wheres,$appendParams = []) :self
    
    ->whereNested('skus',function(Es $query){
        $query->where('skus.title','iphone')->where('skus.des','iphone');
    },['inner_hits'=>['highlight' => ['fields'=>['skus.title'=>new \stdClass()]]]]);
    
    ->whereNested('skus',['skus.title' => 'iphone','skus.description' => 'iphone',['skus.price','>','100']],['inner_hits'=>['highlight' => ['fields'=>['skus.title'=>new \stdClass()]]]]);

    public function postWhere($field, $operator = null, $value = null, $boolean = 'and',$not = false) :self
    
    ->postWhere('platform','wx')
    ->postWhere(['platform' => ['wx','web'],['news_posttime','>','2020-09-01 00:00:00']])
    ->postWhere(function(Es $query){
        $query->where('platform','wx')->whereNotMatch('news_title','安徽合肥')->orWhereIn('news_postdate',['2020-09-01','2020-09-02']);
    })

    public function when($value,$callback,$default = null) :self
    
    ->when(1 > 2,function($query){
        return $query->whereBetween('news_postdate',['2020-05-01','2020-05-05']);
    },function($query){
        return $query->whereBetween('news_postdate',['2020-05-09','2020-05-10']);
    })

    public function collapse(string $field,array $appendParams = []) :self
    
    ->collapse('news_sim_hash')
    ->collapse('news_sim_hash')->aggs('alias','cardinality',['field'=>'news_sim_hash'])
    ->collapse('news_sim_hash')->cardinality('news_sim_hash')
    ->collapse('news_sim_hash')->paginator()

    public function from(int $value) :self

    public function size(int $value) :self

    public function orderBy(string $field, $sort = 'asc') :self
    
    ->orderBy('news_posttime','asc')->orderBy('news_like_count','desc')

    public function highlight(string $field,array $params = [])
    public function highlightConfig(array $config = [])
    
    ->highlightConfig(['

    public function aggs(string $alias,string $type = 'terms',$params = [], ... $subGroups) :self
    
    ->aggs('alias','terms',['field'=>'platform','size'=>15,'order' => ['_count'=>'asc']])
    ->aggs('alias','date_histogram',['field'=>'news_posttime','interval' => 'day','format' => 'yyyy-MM-dd','min_doc_count' => 0])
    ->aggs('alias','histogram',['field'=>'news_like_count','interval'=>10])
    ->aggs('alias','extended_stats',['field'=>'news_like_count'])
    ->aggs('alias','cardinality',['field'=>'news_sim_hash'])
    ->aggs('alias','avg',['field'=>'news_like_count'])
    ->aggs('alias','sum',['field'=>'news_like_count'])
    ->aggs('alias','min',['field'=>'news_like_count'])
    ->aggs('alias','max',['field'=>'news_like_count'])
    ->aggs('alias','date_range',[
        'field' => 'news_posttime',
        'format'=> 'yyyy-MM-dd',
        'ranges'=>[
            ['from'=>'2020-09-01','to'=>'2020-09-02'],
            ['from'=>"2020-09-02",'to'=>'2020-09-03']
        ]
    ])
    ->aggs('alias','range',[
        'field' => 'media_CI',
        'ranges'=>[
            ['key'=>'0-500','to'=>'500'],
            ['key'=>'500-1000','from'=>'500','to'=>'1000'],
            ['key'=>'1000-∞','from'=>'1000'],
        ]
    ])
    ->aggs('alias','top_hits',['size'=>1])
    ->aggs('alias','filter',['term' => ['platform' => 'web']])

    public function groupBy(string $field, array $appendParams = [], ... $subGroups) :self
    
    ->groupBy('platform',['size'=>20,'order'=>['_count'=>'asc']])
    
    // $appendParams 常用的一些设置,不同的聚合类型参数不同
    $appendParams = [
        'size' => 10,                   // 默认
        'order' => ['_count'=>'desc']   // 默认,文档数量倒序
        'order' => ['_count'=>'asc']    // 文档数量顺序
        'order' => ['_key'=>'desc']     // 分组key倒序
        'order' => ['_key'=>'asc']      // 分组key顺序
        ...
    ]

    public function dateGroupBy(string $field,string $interval = 'day',string $format = "yyyy-MM-dd",array $appendParams = [], ... $subGroups) :self
    
    ->dateGroupBy('news_posttime','day','yyyy-MM-dd')

    public function cardinality(string $field,array $appendParams = []) :self
    
    ->cardinality('news_sim_hash')

    public function avg(string $field,array $appendParams = []) :self
    
    ->avg('media_CI')

    public function sum(string $field,array $appendParams = []) :self
    
    ->sum('media_CI')

    public function min(string $field,array $appendParams = []) :self
    
    ->min('media_CI')

    public function max(string $field,array $appendParams = []) :self
    
    ->max('media_CI')

    public function stats(string $field,array $appendParams = []) :self
    
    ->stats('media_CI')

    public function extendedStats(string $field,array $appendParams = []) :self
    
    ->extendedStats('media_CI')

    public function topHits($params) :self
    
    ->topHits([
        'from' => 2,
        'size' => 1,
        'sort' => ['news_posttime' => ['order' => 'asc']],
        '_source' => ['news_title','news_posttime','news_url','news_digest'],
        'highlight' => [
            '->size(1)->from(2)
            ->orderBy('news_posttime','asc')
            ->select(['news_title','news_posttime','news_url','news_digest'])
            ->highlight('news_title')
            ->highlight('news_digest',['number_of_fragments' => 0]);
    })

    public function aggsFilter($alias,$wheres,... $subGroups) :self
    
    ->aggsFilter('alias1',function(Es $query){
        $query->where('platform','web');
    },function(Es $query){
        $query->groupBy('platform_name',['size'=>30]);
    })
    ->aggsFilter('alias2',['platform'=>'web','news_title'=>'合肥',['news_postdate','>=','2020-09-01']],function(Es $query){
        $query->groupBy('platform_name',['size'=>30]);
    })

    public function raw($dsl) :self
    
    ->raw(['query'=>['match_all' => new \stdClass()]])->get()
    ->raw(json_encode(['query'=>['match_all' => new \stdClass()]]))->get()

    public function dsl($type = 'array')

    public function get($directReturn = false)
    
    // $directReturn = false时,返回以下数据
    [
        'total'     => 文档总数,
        'list'      => 文档列表,
        'aggs'      => 聚合结果(存在聚合时返回),
        'scroll_id' => scroll_id(游标查询时返回)
    ]

    public function paginator(int $page = 1, int $size = 10)
    
    ->collapse('news_sim_hash')->paginator()
    
    [
        'total'             => 文档总数(存在collapse时,是计算折叠后的总数),
        'original_total'    => 文档总数(不受collapse影响),
        'per_page'          => 每页条数,
        'current_page'      => 当前页码,
        'last_page'         => 最大页码,
        'list'              => 文档列表,
        'aggs'              => 聚合结果(存在聚合时返回)
    ]

    public function first($directReturn = false)

    public function count()

    $data = Es::init()->scroll()->size(1000)->where('platform','app')->get();
    $es = Es::init();
    while(true){
        $data = $es->scrollId($data['scroll_id'])->get();
        // do something
        ...
    }

    // 本例实现的是多个关键词组短语匹配,词组之间是or关系,词组内为and关系
    $keywordGroups = [
        ['中国','上海'],
        ['安徽','合肥'],
    ];
    public function keywords($keywordGroups,$type = 'full'){
        $this->where(function(self $query)use($keywordGroups,$type){
            foreach($keywordGroups as $keywordGroup){
                $query->orWhere(function(self $query1)use($keywordGroup,$type){
                    foreach($keywordGroup as $keyword){
                        if('full' == $type){
                            $query1->whereMultiMatch(['news_title','news_content'],$keyword,'phrase',["operator" => "OR"]);
                        }elseif('title' == $type){
                            $query1->whereMatch('news_title',$keyword,'match_phrase');
                        }elseif('content' == $type){
                            $query1->whereMatch('news_content',$keyword,'match_phrase');
                        }
                    }
                });
            }
        });
        return $this;
    }

    // 本例实现的是排除关键词组内的关键词
    $keywords = ['美国','日本'];
    public function keywordsExclude($keywords){
        $this->where(function(self $query)use($keywords){
            foreach($keywords as $keyword){
                $query->whereNotMultiMatch(['news_title','news_content'],$keyword,'phrase',["operator" => "OR"]);
            }
        });
        return $this;
    }

    public function query()
    {
        if(!is_string($this->dsl)){
            $this->dsl = json_encode($this->dsl,JSON_UNESCAPED_UNICODE);
        }
        
        /****用内部组装好的$this->dsl进行查询,并返回es的响应...****/

        return $response;
    }

    Es::init()->select('id','name')->where('id',3)->dsl();
    Es::init()->select('id','name')->where('id',3)->groupBy('platform_name')->get();
    Es::init()->select('id','name')->where('id',3)->paginator(2,15);
    Es::init()->select('id','name')->where('id',3)->first();
    Es::init()->select('id','name')->where('id',3)->count();
    
    Es::init()->select('news_title','news_url','news_uuid','platform')
    ->where('platform',['wx','web','app'])
    ->whereBetween('news_postdate',['2020-09-01','2020-09-10'])
    ->keywords([['中国','上海'],['安徽','合肥']],'full')
    ->keywordsExclude(['美国','日本'])
    ->highlight('news_title')
    ->groupBy('platform',['size'=>20,'order'=>['_count'=>'asc']],function(Es $query){
        $query->groupBy('platform_name',['size'=>30]);
    },function(Es $query){
        $query->groupBy('platform_domian_pri',['size'=>30],function(Es $query){
            $query->topHits(['size'=>1]);
        });
    })
    ->dateGroupBy('news_posttime')
    ->aggs('news_like_count','histogram',['interval'=>100])
    ->cardinality('news_sim_hash')
    ->avg('media_CI')
    ->sum('media_CI')
    ->max('media_CI')
    ->min('media_CI')
    ->extendedStats('media_CI')
    ->get();