carlosocarvalho/elasticsearch

Laravel, Lumen 和原生 PHP Elasticsearch 查询构建器,使用优雅的语法构建复杂查询。这是从 carlosocarvalho 分支出来的。

安装: 333

依赖项: 0

建议者: 0

安全: 0

星标: 0

关注者: 2

分支: 130

类型:

v1.5.1 2024-05-24 14:33 UTC

README

Build Status Latest Stable Version Total Downloads License

Laravel, Lumen 和原生 PHP Elasticsearch 查询构建器,使用优雅的语法构建复杂查询

  • 让您远离浪费时间,通过将数组查询替换为简单而优雅的语法,您将爱不释手。
  • 受 Laravel Eloquent 启发的 Elasticsearch 数据模型,用于类型和索引。
  • 可以自由地通过简单的 artisan 控制台命令创建、删除、映射和重新索引。
  • Lumen 框架支持。
  • 原生 PHP 和基于 composer 的应用程序支持。
  • 可以作为 Laravel Scout 驱动程序使用。
  • 同时处理多个 Elasticsearch 连接。
  • 基于 LengthAwarePagination 的出色分页。
  • 使用基于 Laravel 缓存 的缓存层缓存查询。

要求

  • php >= 5.6.6

    查看 Travis CI 构建

  • laravel/laravel >= 5.* 或 laravel/lumen >= 5.* 或 composer application

文档

查看 完整文档

安装

Laravel 安装

1) 使用 composer 安装包。
$ composer require carlosocarvalho/elasticsearch
2) 添加包服务提供者(< laravel 5.5)。
CarlosOCarvalho\Elasticsearch\ElasticsearchServiceProvider::class
3) 添加包别名(< laravel 5.5)。
'ES' => CarlosOCarvalho\Elasticsearch\Facades\ES::class
4) 发布。
$ php artisan vendor:publish --provider="CarlosOCarvalho\Elasticsearch\ElasticsearchServiceProvider"

Lumen 安装

1) 使用 composer 安装包。
$ composer require carlosocarvalho/elasticsearch
2) 在 bootstrap/app.php 中添加包服务提供者。
$app->register(CarlosOCarvalho\Elasticsearch\ElasticsearchServiceProvider::class);
3) 将包配置目录 vendor/carlosocarvalho/elasticsearch/src/config 复制到根目录,与 app 目录一起。
4) 通过在 bootstrap/app.php 中取消注释此行使 Lumen 的工作与外观协同工作。
$app->withFacades();

如果您不想启用与 Lumen 外观协同工作,您可以使用 app("es") 访问查询构建器。

app("es")->index("my_index")->type("my_type")->get();

# is similar to 

ES::index("my_index")->type("my_type")->get();

Composer 安装

您可以使用 composer 基于的任何应用程序安装包

1) 使用 composer 安装包。
$ composer require carlosocarvalho/elasticsearch
2) 创建连接。
require "vendor/autoload.php";

use CarlosOCarvalho\Elasticsearch\Connection;

$connection = Connection::create([
    'servers' => [
        [
            "host" => '127.0.0.1',
            "port" => 9200,
            'user' => '',
            'pass' => '',
            'scheme' => 'http',
        ],
    ],
    
	// Custom handlers
	// 'handler' => new MyCustomHandler(),

    'index' => 'my_index',
    
    'logging' => [
        'enabled'   => env('ELASTIC_LOGGING_ENABLED',false),
        'level'     => env('ELASTIC_LOGGING_LEVEL','all'),
        'location'  => env('ELASTIC_LOGGING_LOCATION',base_path('storage/logs/elasticsearch.log'))
    ],  
]);


# access the query builder using created connection

$documents = $connection->search("hello")->get();

配置(Laravel & Lumen)

发布后,将创建两个配置文件。

  • config/es.php 其中您可以添加多个 Elasticsearch 服务器。
# Here you can define the default connection name.

'default' => env('ELASTIC_CONNECTION', 'default'),

# Here you can define your connections.

'connections' => [
	'default' => [
	    'servers' => [
	        [
	            "host" => env("ELASTIC_HOST", "127.0.0.1"),
	            "port" => env("ELASTIC_PORT", 9200),
	            'user' => env('ELASTIC_USER', ''),
	            'pass' => env('ELASTIC_PASS', ''),
	            'scheme' => env('ELASTIC_SCHEME', 'http'),
	        ]
	    ],
	    
		// Custom handlers
		// 'handler' => new MyCustomHandler(),
		
		'index' => env('ELASTIC_INDEX', 'my_index')
	]
],
 
# Here you can define your indices.
 
'indices' => [
	'my_index_1' => [
	    "aliases" => [
	        "my_index"
	    ],
	    'settings' => [
	        "number_of_shards" => 1,
	        "number_of_replicas" => 0,
	    ],
	    'mappings' => [
	        'posts' => [
                'properties' => [
                    'title' => [
                        'type' => 'string'
                    ]
                ]
	        ]
	    ]
	]
]
  • config/scout.php 其中您可以使用包作为 Laravel Scout 驱动程序。

在控制台环境中工作(Laravel & Lumen)

通过一些 artisan 命令,您可以执行一些任务,例如创建或更新设置、映射和别名。

请注意,所有命令都在 --connection=default 选项下运行,您可以通过命令更改它。

这些都是所有可用的命令

列出服务器上的所有索引

$ php artisan es:indices:list

+----------------------+--------+--------+----------+------------------------+-----+-----+------------+--------------+------------+----------------+
| configured (es.php)  | health | status | index    | uuid                   | pri | rep | docs.count | docs.deleted | store.size | pri.store.size |
+----------------------+--------+--------+----------+------------------------+-----+-----+------------+--------------+------------+----------------+
| yes                  | green  | open   | my_index | 5URW60KJQNionAJgL6Q2TQ | 1   | 0   | 0          | 0            | 260b       | 260b           |
+----------------------+--------+--------+----------+------------------------+-----+-----+------------+--------------+------------+----------------+

创建在 es.php 配置文件中定义的索引

请注意,创建操作会跳过已存在的索引。

# Create all indices in config file.

$ php artisan es:indices:create

# Create only 'my_index' index in config file

$ php artisan es:indices:create my_index 

更新在 es.php 配置文件中定义的索引

请注意,更新操作更新索引设置、别名和映射,但不删除已索引的数据。

# Update all indices in config file.

$ php artisan es:indices:update

# Update only 'my_index' index in config file

$ php artisan es:indices:update my_index 

删除索引

当使用此命令时请小心,您将丢失索引数据!

使用 --force 选项运行删除命令将跳过所有确认消息。

# Drop all indices in config file.

$ php artisan es:indices:drop

# Drop specific index on sever. Not matter for index to be exist in config file or not.

$ php artisan es:indices:drop my_index 

零停机时间重新索引数据

首先,为什么需要重新索引?

更改索引映射不会反映出来,除非重新索引数据,否则您的搜索结果将无法正确工作。

为了避免停机时间,您的应用程序应使用索引 alias 而不是索引 name 进行工作。

索引 alias 是一个常量名称,应用程序应使用该名称以避免更改索引名称。

假设我们想更改 my_index 的映射,这样做
  1. alias 添加为示例 my_index_aliasmy_index 配置中,并确保应用程序正在使用它。
"aliases" => [
    "my_index_alias"
]       
  1. 使用命令更新索引
$ php artisan es:indices:update my_index
  1. 创建一个新索引,例如 my_new_index,并在配置文件中使用新的映射。
$ php artisan es:indices:create my_new_index
  1. 使用命令将数据从 my_index 重新索引到 my_new_index
$ php artisan es:indices:reindex my_index my_new_index

# Control bulk size. Adjust it with your server.

$ php artisan es:indices:reindex my_index my_new_index --bulk-size=2000

# Control query scroll value.

$ php artisan es:indices:reindex my_index my_new_index --bulk-size=2000 --scroll=2m

# Skip reindexing errors such as mapper parsing exceptions.

$ php artisan es:indices:reindex my_index my_new_index --bulk-size=2000 --skip-errors 

# Hide all reindexing errors and show the progres bar only.

$ php artisan es:indices:reindex my_index my_new_index --bulk-size=2000 --skip-errors --hide-errors
  1. my_index 中删除 my_index_alias 别名,并将其添加到配置文件中的 my_new_index,然后使用命令更新
$ php artisan es:indices:update

作为 Laravel Scout 驱动器的用法

首先,按照 Laravel Scout 安装 进行操作。

您需要做的就是更新 config/scout.php 配置文件中的这些行。

# change the default driver to 'es'
	
'driver' => env('SCOUT_DRIVER', 'es'),
	
# link `es` driver with default elasticsearch connection in config/es.php
	
'es' => [
    'connection' => env('ELASTIC_CONNECTION', 'default'),
],

查看 laravel Scout 文档

Elasticsearch 数据模型

每个索引类型都有一个对应的 "Model",用于与该类型交互。模型允许您查询类型或索引中的数据,以及将新文档插入到类型中。

基本用法
<?php

namespace App;

use CarlosOCarvalho\Elasticsearch\Model;

class Post extends Model
{
        
    protected $type = "posts";
    
}

上述示例将使用默认连接和默认索引 es.php 中的索引。您可以在下一个示例中覆盖这两个。

<?php

namespace App;

use CarlosOCarvalho\Elasticsearch\Model;

class Post extends Model
{
    
    # [optional] Default: default elasticsearch driver
    # To override default conenction name of es.php file.
    # Assumed that there is a connection with name 'my_connection'
    protected $connection = "my_connection";
    
    # [optional] Default: default connection index
    # To override default index name of es.php file.
    protected $index = "my_index";
    
    protected $type = "posts";
    
}
检索模型

一旦创建了模型及其关联的索引类型,您就可以开始从索引中检索数据了。例如

<?php

use App\Post;

$posts = App\Post::all();

foreach ($posts as $post) {
    echo $post->title;
}
添加额外约束

all 方法将返回模型类型的所有结果。每个 Elasticsearch 模型都充当查询构建器,您也可以向查询添加约束,然后使用 get() 方法检索结果

$posts = App\Post::where('status', 1)
               ->orderBy('created_at', 'desc')
               ->take(10)
               ->get();
检索单个模型
// Retrieve a model by document key...
$posts = App\Post::find("AVp_tCaAoV7YQD3Esfmp");
插入模型

要创建一个新文档,只需创建一个新的模型实例,设置模型上的属性,然后调用 save() 方法

<?php

namespace App\Http\Controllers;

use App\Post;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    /**
     * Create a new post instance.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        // Validate the request...

        $post = new Post;

        $post->title = $request->title;

        $post->save();
    }
}
更新模型

save() 方法也可以用于更新已存在的模型。要更新模型,您应该检索它,设置您希望更新的任何属性,然后调用保存方法。

$post = App\Post::find(1);

$post->title = 'New Post Title';

$post->save();
删除模型

要删除模型,请在对模型实例调用 delete() 方法

$post = App\Post::find(1);

$post->delete();
查询作用域

作用域允许您定义可以在应用程序中轻松重用的常见约束集。例如,您可能需要频繁检索所有被认为是 "热门" 的帖子。要定义作用域,只需在 Eloquent 模型方法前加上作用域。

作用域应始终返回一个查询实例。

<?php

namespace App;

use CarlosOCarvalho\Elasticsearch\Model;

class Post extends Model
{
    /**
     * Scope a query to only include popular posts.
     *
     * @param \CarlosOCarvalho\Elasticsearch\Query $query
     * @return \CarlosOCarvalho\Elasticsearch\Query
     */
    public function scopePopular($query, $votes)
    {
        return $query->where('votes', '>', $votes);
    }

    /**
     * Scope a query to only include active posts.
     *
     * @param \CarlosOCarvalho\Elasticsearch\Query $query
     * @return \CarlosOCarvalho\Elasticsearch\Query
     */
    public function scopeActive($query)
    {
        return $query->where('active', 1);
    }
}

作用域定义后,您可以在查询模型时调用作用域方法。但是,在调用方法时不需要包含作用域前缀。您甚至可以链式调用各种作用域,例如

$posts = App\Post::popular(100)->active()->orderBy('created_at')->get();
访问器和修改器
定义访问器

要定义 accessor,在您的模型上创建一个名为 getFooAttribute 的方法,其中 Foo 是您希望访问的列的 "studly" 大写名称。在这个例子中,我们将为 title 属性定义一个访问器。访问器将自动由模型在尝试检索 title 属性的值时调用

<?php

namespace App;

use CarlosOCarvalho\Elasticsearch\Model;

class post extends Model
{
    /**
     * Get the post title.
     *
     * @param  string  $value
     * @return string
     */
    public function getTitleAttribute($value)
    {
        return ucfirst($value);
    }
}

如你所见,原始列的值传递给访问器,这允许你操纵并返回值。要访问访问器的值,您只需在模型实例上访问 title 属性即可

$post = App\Post::find(1);

$title = $post->title;

有时,您可能需要添加没有在索引中对应字段的数组属性。为此,只需为该值定义一个访问器

public function getIsPublishedAttribute()
{
    return $this->attributes['status'] == 1;
}

一旦创建了访问器,只需将其添加到模型上的 appends 属性中

protected $appends = ['is_published'];

一旦属性被添加到 appends 列表中,它将包含在模型的数组中。

定义一个修改器

要定义一个修改器,在你的模型上定义一个 setFooAttribute 方法,其中 Foo 是你希望访问的列的“大写字母”命名。所以,再次,让我们定义一个 title 属性的修改器。当尝试在模型上设置 title 属性的值时,这个修改器将被自动调用

<?php

namespace App;

use CarlosOCarvalho\Elasticsearch\Model;

class post extends Model
{
    /**
     * Set the post title.
     *
     * @param  string  $value
     * @return void
     */
    public function setTitleAttribute($value)
    {
        return strtolower($value);
    }
}

修改器将接收正在设置的属性值,允许你操纵该值,并将操纵后的值设置在模型内部 $attributes 属性上。例如,如果我们尝试将标题属性设置为 Awesome post to read

$post = App\Post::find(1);

$post->title = 'Awesome post to read';

在这个例子中,setTitleAttribute 函数将使用值 Awesome post to read 被调用。修改器将应用 strtolower 函数到名称上,并将结果值设置在内部 $attributes 数组中。

属性转换

模型上的 $casts 属性提供了一个方便的方法来将属性转换为常见的数据类型。$casts 属性应该是一个数组,其中键是要转换的属性名称,值是你希望将列转换为的数据类型。支持的数据类型转换有:integerfloatdoublestringbooleanobjectarray

例如,让我们将存储在索引中的整数(0或1)的 is_published 属性转换为 boolean

<?php

namespace App;

use CarlosOCarvalho\Elasticsearch\Model;

class Post extends Model
{
    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'is_published' => 'boolean',
    ];
}

现在,当访问 is_published 属性时,它将始终转换为 boolean 值,即使底层值在索引中作为整数存储

$post = App\Post::find(1);

if ($post->is_published) {
    //
}

作为查询构建器的用法

创建新索引

ES::create("my_index");
    
# or 
    
ES::index("my_index")->create();
创建带有自定义选项的索引(可选)
ES::index("my_index")->create(function($index){
        
    $index->shards(5)->replicas(1)->mapping([
        'my_type' => [
            'properties' => [
                'first_name' => [
                    'type' => 'string',
                ],
                'age' => [
                    'type' => 'integer'
                ]
            ]
        ]
    ])
    
});
    
# or
    
ES::create("my_index", function($index){
  
      $index->shards(5)->replicas(1)->mapping([
          'my_type' => [
              'properties' => [
                  'first_name' => [
                      'type' => 'string',
                  ],
                  'age' => [
                      'type' => 'integer'
                  ]
              ]
          ]
      ])
  
});

删除索引

ES::drop("my_index");
    
# or
    
ES::index("my_index")->drop();

运行查询

$documents = ES::connection("default")
                ->index("my_index")
                ->type("my_type")
                ->get();    # return a collection of results

你可以将上述查询重写为

$documents = ES::type("my_type")->get();    # return a collection of results

查询构建器将使用默认连接,配置文件 es.php 中的索引名称。

查询中的连接和索引名称覆盖配置文件 es.php 中的连接和索引名称。

通过 id 获取文档
ES::type("my_type")->id(3)->first();
    
# or
    
ES::type("my_type")->_id(3)->first();
排序
ES::type("my_type")->orderBy("created_at", "desc")->get();
    
# Sorting with text search score
    
ES::type("my_type")->orderBy("_score")->get();
限制和偏移量
ES::type("my_type")->take(10)->skip(5)->get();
仅选择特定字段
ES::type("my_type")->select("title", "content")->take(10)->skip(5)->get();
WHERE 子句
ES::type("my_type")->where("status", "published")->get();

# or

ES::type("my_type")->where("status", "=", "published")->get();
WHERE 大于
ES::type("my_type")->where("views", ">", 150)->get();
WHERE 大于等于
ES::type("my_type")->where("views", ">=", 150)->get();
WHERE 小于
ES::type("my_type")->where("views", "<", 150)->get();
WHERE 小于等于
ES::type("my_type")->where("views", "<=", 150)->get();
WHERE 如
ES::type("my_type")->where("title", "like", "foo")->get();
WHERE 字段存在
ES::type("my_type")->where("hobbies", "exists", true)->get(); 

# or 

ES::type("my_type")->whereExists("hobbies", true)->get();
WHERE IN 子句
ES::type("my_type")->whereIn("id", [100, 150])->get();
WHERE BETWEEN 子句
ES::type("my_type")->whereBetween("id", 100, 150)->get();

# or 

ES::type("my_type")->whereBetween("id", [100, 150])->get();
WHERE NOT 子句
ES::type("my_type")->whereNot("status", "published")->get(); 

# or

ES::type("my_type")->whereNot("status", "=", "published")->get();
WHERE NOT 大于
ES::type("my_type")->whereNot("views", ">", 150)->get();
WHERE NOT 大于等于
ES::type("my_type")->whereNot("views", ">=", 150)->get();
WHERE NOT 小于
ES::type("my_type")->whereNot("views", "<", 150)->get();
WHERE NOT 小于等于
ES::type("my_type")->whereNot("views", "<=", 150)->get();
WHERE NOT 如
ES::type("my_type")->whereNot("title", "like", "foo")->get();
WHERE NOT 字段存在
ES::type("my_type")->whereNot("hobbies", "exists", true)->get(); 

# or

ES::type("my_type")->whereExists("hobbies", true)->get();
WHERE NOT IN 子句
ES::type("my_type")->whereNotIn("id", [100, 150])->get();
WHERE NOT BETWEEN 子句
ES::type("my_type")->whereNotBetween("id", 100, 150)->get();

# or

ES::type("my_type")->whereNotBetween("id", [100, 150])->get();
从地理点搜索距离
ES::type("my_type")->distance("location", ["lat" => -33.8688197, "lon" => 151.20929550000005], "10km")->get();

# or

ES::type("my_type")->distance("location", "-33.8688197,151.20929550000005", "10km")->get();

# or

ES::type("my_type")->distance("location", [151.20929550000005, -33.8688197], "10km")->get();  
使用数组查询搜索
ES::type("my_type")->body([
    "query" => [
         "bool" => [
             "must" => [
                 [ "match" => [ "address" => "mill" ] ],
                 [ "match" => [ "address" => "lane" ] ]
             ]
         ]
     ]
])->get();

# Note that you can mix between query builder and array queries.
# The query builder will will be merged with the array query.

ES::type("my_type")->body([

	"_source" => ["content"]
	
	"query" => [
	     "bool" => [
	         "must" => [
	             [ "match" => [ "address" => "mill" ] ]
	         ]
	     ]
	],
	   
	"sort" => [
		"_score"
	]
     
])->select("name")->orderBy("created_at", "desc")->take(10)->skip(5)->get();

# The result query will be
/*
Array
(
    [index] => my_index
    [type] => my_type
    [body] => Array
        (
            [_source] => Array
                (
                    [0] => content
                    [1] => name
                )
            [query] => Array
                (
                    [bool] => Array
                        (
                            [must] => Array
                                (
                                    [0] => Array
                                        (
                                            [match] => Array
                                                (
                                                    [address] => mill
                                                )
                                        )
                                )
                        )
                )
            [sort] => Array
                (
                    [0] => _score
                    [1] => Array
                        (
                            [created_at] => desc
                        )
                )
        )
    [from] => 5
    [size] => 10
    [client] => Array
        (
            [ignore] => Array
                (
                )
        )
)
*/
搜索整个文档
ES::type("my_type")->search("hello")->get();
    
# search with Boost = 2
    
ES::type("my_type")->search("hello", 2)->get();

# search within specific fields with different weights

ES::type("my_type")->search("hello", function($search){
	$search->boost(2)->fields(["title" => 2, "content" => 1])
})->get();
仅返回第一条记录
ES::type("my_type")->search("hello")->first();
仅返回计数
ES::type("my_type")->search("hello")->count();
Scan-and-Scroll 查询
# These queries are suitable for large amount of data. 
# A scrolled search allows you to do an initial search and to keep pulling batches of results
# from Elasticsearch until there are no more results left.
# It’s a bit like a cursor in a traditional database
    
$documents = ES::type("my_type")->search("hello")
                 ->scroll("2m")
                 ->take(1000)
                 ->get();

# Response will contain a hashed code `scroll_id` will be used to get the next result by running

$documents = ES::type("my_type")->search("hello")
                 ->scroll("2m")
                 ->scrollID("DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAFMFlJQOEtTdnJIUklhcU1FX2VqS0EwZncAAAAAAAABSxZSUDhLU3ZySFJJYXFNRV9laktBMGZ3AAAAAAAAAU4WUlA4S1N2ckhSSWFxTUVfZWpLQTBmdwAAAAAAAAFPFlJQOEtTdnJIUklhcU1FX2VqS0EwZncAAAAAAAABTRZSUDhLU3ZySFJJYXFNRV9laktBMGZ3")
                 ->get();

# And so on ...
# Note that you don't need to write the query parameters in every scroll. All you need the `scroll_id` and query scroll time.
    
# To clear `scroll_id` 
  
ES::type("my_type")->scrollID("DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAFMFlJQOEtTdnJIUklhcU1FX2VqS0EwZncAAAAAAAABSxZSUDhLU3ZySFJJYXFNRV9laktBMGZ3AAAAAAAAAU4WUlA4S1N2ckhSSWFxTUVfZWpLQTBmdwAAAAAAAAFPFlJQOEtTdnJIUklhcU1FX2VqS0EwZncAAAAAAAABTRZSUDhLU3ZySFJJYXFNRV9laktBMGZ3")
        ->clear();
每页5条记录分页
$documents = ES::type("my_type")->search("hello")->paginate(5);
    
# Getting pagination links
    
$documents->links();

# Bootstrap 4 pagination

$documents->links("bootstrap-4");

# Simple bootstrap 4 pagination

$documents->links("simple-bootstrap-4");

# Simple pagination

$documents->links("simple-default");

这些都是你可以使用的分页方法

$documents->count()
$documents->currentPage()
$documents->firstItem()
$documents->hasMorePages()
$documents->lastItem()
$documents->lastPage()
$documents->nextPageUrl()
$documents->perPage()
$documents->previousPageUrl()
$documents->total()
$documents->url($page)
获取不执行的查询数组
ES::type("my_type")->search("hello")->where("views", ">", 150)->query();
获取原始 elasticsearch 响应
ES::type("my_type")->search("hello")->where("views", ">", 150)->response();
忽略坏的 HTTP 响应
ES::type("my_type")->ignore(404, 500)->id(5)->first();
查询缓存(Laravel & Lumen)

该包包含一个基于 laravel 缓存的内置缓存层。

ES::type("my_type")->search("hello")->remember(10)->get();
	
# Specify a custom cache key

ES::type("my_type")->search("hello")->remember(10, "last_documents")->get();
	
# Caching using other available driver
	
ES::type("my_type")->search("hello")->cacheDriver("redis")->remember(10, "last_documents")->get();
	
# Caching with cache key prefix
	
ES::type("my_type")->search("hello")->cacheDriver("redis")->cachePrefix("docs")->remember(10, "last_documents")->get();
执行 elasticsearch 原始查询
ES::raw()->search([
    "index" => "my_index",
    "type"  => "my_type",
    "body" => [
        "query" => [
            "bool" => [
                "must" => [
                    [ "match" => [ "address" => "mill" ] ],
                    [ "match" => [ "address" => "lane" ] ]
                ]
            ]
        ]
    ]
]);
插入新文档
ES::type("my_type")->id(3)->insert([
    "title" => "Test document",
    "content" => "Sample content"
]);
     
# A new document will be inserted with _id = 3.
  
# [id is optional] if not specified, a unique hash key will be generated.
一次性批量插入多个文档。
# Main query

ES::index("my_index")->type("my_type")->bulk(function ($bulk){

    # Sub queries

	$bulk->index("my_index_1")->type("my_type_1")->id(10)->insert(["title" => "Test document 1","content" => "Sample content 1"]);
	$bulk->index("my_index_2")->id(11)->insert(["title" => "Test document 2","content" => "Sample content 2"]);
	$bulk->id(12)->insert(["title" => "Test document 3", "content" => "Sample content 3"]);
	
});

# Notes from the above query:

# As index and type names are required for insertion, Index and type names are extendable. This means that: 

# If index() is not specified in subquery:
# -- The builder will get index name from the main query.
# -- if index is not specified in main query, the builder will get index name from configuration file.

# And

# If type() is not specified in subquery:
# -- The builder will get type name from the main query.

# you can use old bulk code style using multidimensional array of [id => data] pairs
 
ES::type("my_type")->bulk([
 
	10 => [
		"title" => "Test document 1",
		"content" => "Sample content 1"
	],
	 
	11 => [
		"title" => "Test document 2",
		"content" => "Sample content 2"
	]
 
]);
 
# The two given documents will be inserted with its associated ids
更新现有文档
ES::type("my_type")->id(3)->update([
   "title" => "Test document",
   "content" => "sample content"
]);
    
# Document has _id = 3 will be updated.
    
# [id is required]
# Bulk update

ES::type("my_type")->bulk(function ($bulk){
    $bulk->id(10)->update(["title" => "Test document 1","content" => "Sample content 1"]);
    $bulk->id(11)->update(["title" => "Test document 2","content" => "Sample content 2"]);
});
递增字段
ES::type("my_type")->id(3)->increment("views");
    
# Document has _id = 3 will be incremented by 1.
    
ES::type("my_type")->id(3)->increment("views", 3);
    
# Document has _id = 3 will be incremented by 3.

# [id is required]
递减字段
ES::type("my_type")->id(3)->decrement("views");
    
# Document has _id = 3 will be decremented by 1.
    
ES::type("my_type")->id(3)->decrement("views", 3);
    
# Document has _id = 3 will be decremented by 3.

# [id is required]
使用脚本更新
# increment field by script
    
ES::type("my_type")->id(3)->script(
    "ctx._source.$field += params.count",
    ["count" => 1]
);
    
# add php tag to tags array list
    
ES::type("my_type")->id(3)->script(
    "ctx._source.tags.add(params.tag)",
    ["tag" => "php"]
);
    
# delete the doc if the tags field contain mongodb, otherwise it does nothing (noop)
    
ES::type("my_type")->id(3)->script(
    "if (ctx._source.tags.contains(params.tag)) { ctx.op = 'delete' } else { ctx.op = 'none' }",
    ["tag" => "mongodb"]
);
删除文档
ES::type("my_type")->id(3)->delete();
    
# Document has _id = 3 will be deleted.
    
# [id is required]
# Bulk delete

ES::type("my_type")->bulk(function ($bulk){
    $bulk->id(10)->delete();
    $bulk->id(11)->delete();
});

版本

查看 变更日志

作者

Basem Khirat - carlosocarvalho@gmail.com - @carlosocarvalho

错误、建议和贡献

感谢所有为这个项目做出贡献的各位

请使用Github来报告错误,以及发表评论或建议。

许可证

MIT

祝您搜索愉快...