georgebohnisch/laravel-elasticsearch-query-builder

: 使用 Eloquent 查询 Elasticsearch

1.0.3 2019-09-03 19:20 UTC

This package is not auto-updated.

Last update: 2024-09-27 07:13:00 UTC


README

使用 Eloquent 查询 Elasticsearch

这个 Laravel 扩展包旨在简化查询 Elasticsearch 的过程。Eloquent 是一个强大的工具,用于访问和操作 RDB 中的数据。然而,它并非专为查询 NoSQL 数据库(如 Elasticsearch)而设计。这个包旨在填补 Laravel 中最流行的 ORM 和 Elasticsearch 之间的差距。

该包仅依赖于官方的 PHP Elasticsearch 包(v6)

PHP 版本

该包在 PHP v7.1 下开发和测试。它应该也与 v7.* 兼容。如果您发现任何兼容性问题,请通过电子邮件联系我。

Elasticsearch 版本

该包在 Elasticsearch v6.* 下开发和测试。它应该也与 v5.* 兼容。如果您发现任何兼容性问题,请通过电子邮件联系我。已确认该包不支持 v5.* 之前的版本。

安装

  • 将以下内容添加到您的 composer.json 文件中

    "shisun/laravel-elasticsearch-query-builder": "dev-master"
  • 在终端中运行 composer update

  • 将包添加到配置文件夹中的 app.php 文件

    'providers' => [
        ...
        Shisun\LaravelElasticsearchQueryBuilder\LaravelElasticsearchQueryBuilderServiceProvider::class,
    ]
  • 如果您的 Elasticsearch 不可用于 localhost:9200,则必须通过运行以下命令发布配置文件:

    $ php artisan vendor:publish --provider="Shisun\LaravelElasticsearchQueryBuilder\LaravelElasticsearchQueryBuilderServiceProvider"
  • (可选)将 config/laravel-elasticsearch-query-builder.php 中的 ES_HOSTS 修改为您的 Elasticsearch 地址

  • 与 Eloquent 模型一起使用

    • EsTrait 添加到您的模型中
      use Shisun\LaravelElasticsearchQueryBuilder\EsTrait;
      
      class User extends Model
      {
          use EsTrait;
      }
    • 启用验证(可选)
      use Shisun\LaravelElasticsearchQueryBuilder\EsTrait;
      class User extends Model
      {
         use EsTrait;
         public $mappingProperties;
         public function __construct($attributes = []) {
             parent::__construct($attributes);
         
             $this->mappingProperties = [
                 'id' => [
                     'type' => 'integer',
                 ],
                 'name' => [
                     'type' => 'text',
                         'index' => true,
                 ],
                 'email' => [
                     'type' => 'keyword'
                 ],
                 'address' => [
                     'type' => 'text'
                 ],
                 'float_example' => [
                     'type' => 'float'
                 ],
                 'multi_fields_example' => [
                     'type' => 'text',
                     'fields' => [
                         'raw' => [
                             'type' => 'keyword'
                         ]
                     ]
                 ],
                 'created_at' => [
                     'type' => 'date',
                     'format' => 'yyyy-MM-dd HH:mm:ss',
                 ],
                 'some_relations' => [
                     'type' => 'nested',
                     'properties' => [
                         ....
                     ]
                 ]
             ];
         }
      }   
    • 设置模型级别的索引和类型名称。向您的模型添加以下两个函数。(可选)
      public function getIndexName() {
          return 'users';
      }
      // type name will be set to index name if this function is not defined.
      public function getTypeName() {
          return 'users';
      }
  • 不使用 Eloquent 使用

    use Shisun\LaravelElasticsearchQueryBuilder\LaravelElasticsearchQueryBuilder as Builder;
    $query = (new Builder())->setOptions([
        'index_name' => 'users',
        'type_name'  => 'users'
    ])->where('name', 'Leo')->get()->toArray();
    // or if you only want to generate the query without getting results
    $query = (new Builder())->where('name', 'Leo')->getBody()

用法

目录

初始化 & 配置

__construct

  • 如果您使用 Eloquent,则无需使用此函数

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      use Shisun\LaravelElasticsearchQueryBuilder\LaravelElasticsearchQueryBuilder as Builder;
      $builder = new Builder();

setOptions

  • 如果您使用 Eloquent,则无需使用此函数

  • 参数

  • 输出

    self

  • 示例

    1. 基本
      use Shisun\LaravelElasticsearchQueryBuilder\LaravelElasticsearchQueryBuilder as Builder;
      $builder = (new Builder())->setOptions([
          'index_name' => 'users',
          'type_name'  => 'users',
          'validation' => false,
          'mapping_properties' => [check the example in the installation section]
      ]);

查询子句

where

  • 参数

  • 输出

    self

  • 示例

    1. = 可以省略
      User::es()->where('id', 1)->first()
    2. * 是通配符操作符
      // Find the user whose name starts with 'Leo'
      User::es()->where('name', '*', 'Leo*')->first()
    3. column 可以是一个函数
      User::es()->where(function($q) {
          $q->orWhere(...)->orWhere(...);
      })->get()->toArray()

whereNull

  • 参数

  • 输出

    self

  • 示例

    1. 查找所有没有名字的用户
      User::es()->whereNull('name')->get()
    2. 查找所有没有地址的用户
      User::es()->whereNull('Addresses')->get()

whereNotNull

  • 参数

  • 输出

    self

  • 示例

    1. 查找所有有名字的用户
      User::es()->whereNotNull('name')->get()
    2. 查找所有至少有一个地址的用户
      User::es()->whereNotNull('Addresses')->get()

orWhere

  • 参数

  • 输出

    self

  • 示例

    1. = 可以省略
      User::es()->orWhere('id', 1)->first()
    2. column 可以是一个函数
      User::es()->orWhere(function($q) {
          $q->where(...)->where(...);
      })->limit(1)->get()->toArray()

whereMatch

  • 用于模糊文本搜索。此功能应仅应用于文本字段。

  • 参数

  • 输出

    self

  • 示例

    1. 没有 options
      User::es()->whereMatch('email', 'shisun@')->first()
    2. options
      User::es()->whereMatch('email', 'shisun@', [
             'query' => 'this will be overrided by $value',
             'operator' => 'and',
             'zero_terms_query' => 'all'
           ])->first()

whereDoesntMatch

  • 参数

  • 输出

    self

  • 示例

    1. 没有 options
      User::es()->whereDoesntMatch('email', 'shisun@')->first()
    2. options
      User::es()->whereDoesntMatch('email', 'shisun@', [
             'query' => 'this will be overrided by $value',
             'operator' => 'and',
             'zero_terms_query' => 'all'
           ])->first()

orWhereMatch

  • 参数

  • 输出

    self

  • 示例

    1. 没有 options
      User::es()->orWhereMatch('email', 'shisun@')->first()
    2. options
      User::es()->orWhereMatch('email', 'shisun@', [
             'query' => 'this will be overrided by $value',
             'operator' => 'and',
             'zero_terms_query' => 'all'
           ])->first()

whereHas

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      // find all users with active someRelations
      User::es()->whereHas('someRelations', function($q) {
          $q->where('status', 'active');
      })->first();
    2. 第一个参数可以是一个函数
      // find all users with either active someRelations or red someOtherRelations
      // Note: the parent 'whereHas' is interchangable with 'where' clause
      User::es()->whereHas(function($q) {
          $q->orWhereHas('someRelations', function($k) {
               $k->where('status', 'active');
          })->orWhereHas('someOtherRelations', function($k) {
               $k->where('color', 'red');
          });
      })->first();

orWhereHas

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      // find all users with either active someRelations or red someOtherRelations
      // Note: the parent 'whereHas' is interchangable with 'where' clause
      User::es()->whereHas(function($q) {
          $q->orWhereHas('someRelations', function($k) {
               $k->where('status', 'active');
          })->orWhereHas('someOtherRelations', function($k) {
               $k->where('color', 'red');
          });
      })->first();

whereHasNull

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      // find all users with no someRelation
      User::es()->whereHasNull('someRelations')->first();
    2. 带有子查询
      // find all users with no someRelation with id = 1
      User::es()->whereHasNull('someRelations', function($q) {
          $q->where('id', 1);
      })->first();

orWhereHasNull

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      // find all users either with no someRelation or named as 'Leo'
      User::es()->where(function($q) {
          $q->orWhereHasNull('someRelations')->orWhere('name', 'Leo');
      })->first();

whereIn

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      // find all users with pending or active status
      User::es()->whereIn('status', ['active', 'pending'])->get();

orWhereIn

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      // find all users with either pending/active status or with name Leo
      User::es()->where(function($q) {
          $q->orWhereIn('status', ['active', 'pending'])->orWhere('name', 'Leo');
      })->get();

whereNotIn

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      // find all users that are not in pending or active status
      User::es()->whereNotIn('status', ['active', 'pending'])->get();

orWhereNotIn

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      // find all users with either not in pending/active status or with name Leo
      User::es()->where(function($q) {
          $q->orWhereNotIn('status', ['active', 'pending'])->orWhere('name', 'Leo');
      })->get();

whereBetween

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      User::es()->whereBetween('id', 1, 5)->first()

orWhereBetween

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      User::es()->orWhereBetween('id', 1, 5)->first()

排序

orderBy

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      User::es()->orderBy('id', 'desc')->get()
    2. 脚本
      // If the category of the item is Laptop then use discount_price for ordering. Otherwise, use listing_price.
      Item::es()->orderBy('id', 'desc', 
                  ['lang' => 'painless', 'source' => "if(doc['category'].value == 'Laptops') {return doc['discount_price'].value;} else {return doc['listing_price'].value;}"])
            ->get()

分页

page

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      // get the first page. 25 users per page.
      User::es()->page(1, 25)->get()

limit

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      // get 25 users.
      User::es()->limit(25)->get()

offset

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      // skip first 25 users.
      User::es()->offset(25)->get()

聚合

aggregate

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      Item::es()->aggregate('group_items_by_categories', function($q) {
          $q->groupBy('category_id');
      })->get()->aggregations();
    2. 带有过滤器
      // get all active and pending items. But only aggregate on the filtered items that are also red.
      // Note: aggregate clause is only applied on the filtered items.
      Item::es()->whereIn('status', ['active', 'pending'])->aggregate('categories', function($q) {
          $q->where('color', 'red')->aggregate('group_by', function($k) {
              $k->groupBy('category_id');
          });
      })->get()->aggregations();
      // this returns
      // [
      //     'categories' => [
      //         'doc_count' => 50,
      //         'group_by'  => [
      //             'doc_count_error_upper_bound' => 0,
      //             'sum_other_doc_count'         => 8,
      //             'buckets' => [
      //                 [
      //                     'key' => 1,
      //                     'doc_count' => 15
      //                 ],
      //                 ...
      //             ]
      //         ]
      //     ]
      //  ]
      // the 'key' in buckets is one of the category_id

aggregateAll

  • 参数

  • 输出

    self

  • 示例

    1. 带有过滤器
      // get all active and pending items. And aggregate on all red items.
      // Note: aggregateAll clause is applied on all items regardless other queries.
      Item::es()->whereIn('status', ['active', 'pending'])->aggregateAll('categories', function($q) {
          $q->where('color', 'red')->aggregate('group_by', function($k) {
              $k->groupBy('category_id');
          });
      })->get()->aggregations();
      // this returns
      // [
      //     'categories' => [
      //         'doc_count' => 50,
      //         'group_by'  => [
      //             'doc_count_error_upper_bound' => 0,
      //             'sum_other_doc_count'         => 8,
      //             'buckets' => [
      //                 [
      //                     'key' => 1,
      //                     'doc_count' => 15
      //                 ],
      //                 ...
      //             ]
      //         ]
      //     ]
      //  ]
      // the 'key' in buckets is one of the category_id

aggregateOn

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      Item::es()->aggregateOn('someRelations', function($q) {
          $q->min('id');
      })->get()->aggregations();
      // this returns
      // [
      //     'some_relations' => [
      //         'doc_count' => 50,
      //         'min_id'  => [
      //             'value' => 1
      //         ]
      //     ]
      //  ]
      // 'some_relations' will be replaced if custom_name is provided

groupBy

  • 参数

  • 输出

    self

  • 查看聚合子句示例

min

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      Item::es()->min('id')->get()->aggregations();
      // or
      Item::es()->aggregate('test', function($q) {
          $q->min('id');
      })->get()->aggregations();
      // They both return. Note: the 'test' in the second example is ignored.
      // [
      //     'min_id' => [
      //         'value' => 1
      //     ]
      //  ]
      // 'min_id' will be replaced if custom_name is provided. The format of the name is 'min_' + column

max

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      Item::es()->max('id')->get()->aggregations();
      // or
      Item::es()->aggregate('test', function($q) {
          $q->max('id');
      })->get()->aggregations();
      // They both return. Note: the 'test' in the second example is ignored.
      // [
      //     'max_id' => [
      //         'value' => 1
      //     ]
      //  ]
      // 'min_id' will be replaced if custom_name is provided. The format of the name is 'max_' + column

avg

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      Item::es()->avg('id')->get()->aggregations();
      // or
      Item::es()->aggregate('test', function($q) {
          $q->avg('id');
      })->get()->aggregations();
      // They both return. Note: the 'test' in the second example is ignored.
      // [
      //     'avg_id' => [
      //         'value' => 1
      //     ]
      //  ]
      // 'min_id' will be replaced if custom_name is provided. The format of the name is 'avg_' + column

sum

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      Item::es()->sum('id')->get()->aggregations();
      // or
      Item::es()->aggregate('test', function($q) {
          $q->sum('id');
      })->get()->aggregations();
      // They both return. Note: the 'test' in the second example is ignored.
      // [
      //     'sum_id' => [
      //         'value' => 1
      //     ]
      //  ]
      // 'min_id' will be replaced if custom_name is provided. The format of the name is 'sum_' + column

其他过滤器

minScore

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      User::es()->whereMatch('name', 'Leo', ['operator' => 'and'])->minScore(5)->get()

with

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      User::es()->with('Addresses', 'Company')->get()

withOut

  • 参数

  • 输出

    self

  • 示例

    1. 基本示例
      User::es()->withOut('Addresses', 'Company')->get()

执行查询

get

scroll

  • 参数

  • 输出

    数组

  • 示例

    1. 基本示例
      User::es()->scroll()

count

  • 输出

    整数

  • 示例

    1. 基本示例
      User::es()->count()

first

  • 参数

  • 输出

    数组|Eloquent

  • 示例

    1. 基本示例
      User::es()->first()

find

  • 参数

  • 输出

    数组

  • 示例

    1. 基本示例
      // get the user with id = 5
      // Note: the key_name can be set by setKeyName or setOptions. The key_name is 'id' by default
      User::es()->find(5)

delete

  • 从Elasticsearch中删除记录。如果记录不存在,则返回false。

  • 参数

  • 输出

    数组

  • 示例

    1. 基本示例
      // delete the user with id = 5
      // Note: the key_name can be set by setKeyName or setOptions. The key_name is 'id' by default
      User::es()->delete(5)

结果操作

toArray

  • 输出

    数组

toEloquent

警告:如果您不使用Eloquent的包,则此功能不起作用。

  • 输出

    Eloquent

rawResults

从Elasticsearch获取原始结果

  • 输出

    数组

aggregations

获取聚合结果

  • 输出

    数组

getAggregationBuckets

这是一个辅助函数,用于获取由agg_name指定的聚合的桶

  • 参数

  • 输出

    数组

  • 示例

    1. 基本示例
      // if the aggregations are
      // this returns
      // [
      //     'categories' => [
      //         'doc_count' => 50,
      //         'group_by'  => [
      //             'doc_count_error_upper_bound' => 0,
      //             'sum_other_doc_count'         => 8,
      //             'buckets' => [
      //                 [
      //                     'key' => 1,
      //                     'doc_count' => 15
      //                 ],
      //                 ...
      //             ]
      //         ]
      //     ]
      //  ]
      // Then you can use getAggregationBuckets('categories') to get the buckets array

paginate

返回分页信息

  • 参数

  • 输出

    数组

  • 示例

    1. 基本
    [
      "pages" => [
        1,
        2,
        3,
        4,
        5,
      ],
      "rows" => 165,
      "active" => 1,
      "totalpages" => 7.0,
      "prev" => false,
      "next" => true,
      "per_page" => 25
    ]

直接查询输出

getQuery

返回正文部分的查询部分

getBody

返回正文

getAggs

返回正文聚合部分

发布历史

元数据

Shisun(Leo) Xia - shisun.xia@hotmail.com

在GNU V3许可下分发。有关更多信息,请参阅LICENSE

https://github.com/ShisunXia/Laravel-Elasticsearch-Query-Builder