michaeljennings/laralastica

一个laravel包,允许您使用elasticsearch搜索eloquent结果。

v3.3.1 2020-02-25 16:45 UTC

README

一个laravel 5包,它增加了使用elasticsearch结果搜索eloquent模型的能力,同时它还处理在保存或删除模型时索引和删除文档。

从3.0升级到3.1+

当在模型上调用search方法时,查询构建器将返回一个Michaeljennings\Laralastica\Eloquent\ResultCollection实例,而不是Illuminate\Database\Eloquent\Collection实例。

// This will return an instance of Michaeljennings\Laralastica\Eloquent\ResultCollection
Model::search(function(Builder $builder) {
  $builder->matchAll();
})->get();

这很有用,因为您可以使用totalHitsmaxScoretotalTime方法。

但是,如果您想使用默认的集合,您可以在模型上覆盖newCollection方法,并返回所需的集合实例。

/**
 * Create a new database notification collection instance.
 *
 * @param array $models
 * @return ResultCollection
 */
public function newCollection(array $models = [])
{
    return new Illuminate\Database\Eloquent\Collection($models);
}

安装

查看下表以了解您需要哪个版本。

通过composer安装,请运行composer require michaeljennings/laralastica或将包添加到您的composer.json文件中。

"michaeljennings/laralastica": "^3.1"

对于Laravel 5.5及以上版本,服务提供者和外观将自动加载。

对于Laravel的较旧版本,您需要在config/app.php中的提供者数组中添加laralastica服务提供者。

'providers' => [

  'Michaeljennings\Laralastica\LaralasticaServiceProvider'

];

该包还包括一个外观,要使用它,请将其添加到config/app.php中的别名数组中。

'aliases' => [

  'Laralastica' => 'Michaeljennings\Laralastica\Facades\Laralastica',

];

配置

最后,使用php artisan vendor:publish发布包配置。配置发布后,您可以通过编辑`config/laralastica.php`文件来设置您的elasticsearch连接。

该包包含2个驱动程序:elastica和null。默认情况下,包将使用elastica驱动程序。null驱动程序主要用于测试目的,您不希望运行elasticsearch实例。

'driver' => 'elastica',

从laralastica 3.0开始,我们现在使用多个索引,而不是在一个索引中的多个类型。要了解原因,请查看这篇关于删除类型的帖子

如果您正在使用多个环境(生产、预发布、测试等),您可以在配置中定义索引前缀。这将添加到搜索、添加文档等操作中的每个索引。

'index_prefix' => 'testing_',

最后,您需要配置您的elasticsearch连接。默认情况下,该包已准备好支持多个连接。

但是,您可以传递任何elastica客户端可以接收的参数,有关更多信息,请参阅elastica文档

要设置连接,请输入您要连接的主机和端口,或连接的URL。

'drivers' => [
  'elastica' => [
    'servers' => [
      [
        'host' => 'localhost',
        'port' => 9200
      ],
      [
        'url' => 'https://user:pass@your-search.com/'
      ]
    ],
  ]
]

用法

要开始使用此包,只需将Searchable特性添加到您要索引和搜索的模型中。

use Illuminate\Database\Eloquent\Model;
use Michaeljennings\Laralastica\Searchable;

class Foo extends Model
{
	use Searchable;
}

一旦添加了特性,它将使用模型事件来监视模型何时保存、删除或恢复,并适当地添加或删除Elasticsearch文档。

设置Elasticsearch索引

要为模型设置Elasticsearch索引,请使用getIndex方法来返回索引的名称。默认情况下,这将返回模型使用的表名。索引必须是小写。

public function getIndex()
{
	return 'foo';
}

设置索引Elasticsearch文档的键

要设置索引Elasticsearch文档的值,请使用'getSearchKey'方法来返回键。默认情况下,这将返回模型的主键。

public function getSearchKey()
{
	return $this->key;
}

设置要索引的属性

要设置模型应索引哪些属性,请使用getIndexableAttributes方法。属性必须作为键值对数组的返回。默认情况下,所有模型属性都将被索引。

public function getIndexableAttributes()
{
	return [
		'foo' => $this->bar,
	];
}

类型转换属性

在Elasticsearch中,每个索引都有一个映射类型,这将确定记录的索引方式,这意味着您必须以相同的格式提供每个对象。为此,我们可以使用Laravel提供的casts属性。

protected $casts = [
	'price' => 'float',
	'active' => 'bool',
	'quantity' => 'int',
	'name' => 'string'
];

偶尔您可能希望对Elasticsearch记录的值进行轻微的类型转换。为此,您可以定义laralasticaCasts属性,这将允许您覆盖casts属性。

protected $casts = [
	'price' => 'float',
];

protected $laralasticaCasts = [
	'price' => 'string',
];

构建您的索引

如果您已经在数据库中有了数据并且想对其进行索引,您可以使用laralastica:index artisan命令。

定义要索引的模型

要开始,您需要设置在laralastica.php配置文件的indexable部分中想要索引的模型。

默认情况下,该包已设置为索引标准App\User类。

'indexable' => [
    'users' => \App\User::class,
]

要添加新模型,我们需要设置一个自定义键来引用该模型,这将允许我们仅索引该模型。

然后值必须是模型类的完全限定路径。

例如,如果我们想要索引一个产品模型,我们可以这样做:

'indexable' => [
    'users' => \App\User::class,
    'products' => \App\Product::class,
]

偶尔您可能想要索引关系数据,如果您有一个大型数据库,这可能需要很长时间来懒加载关系。为了解决这个问题,您可以在索引时指定要加载的关系。

'indexable' => [
    'users' => \App\User::class,
    'products' => [
        'model' => \App\Product::class,
        'with' => [
            'category' => function($query) {
                $query->with('subcategories');
            }
        ]
    ]
]

索引

如果您想要索引已设置的模型,则可以运行

php artisan laralastica:index

要运行特定的索引,运行

php artisan laralastica:index [your-index]

// For our example above it would be 
php artisan laralastica:index products 

如果您正在索引大量数据,您可能希望将其推送到队列,您可以通过提供队列选项来完成此操作

php artisan laralastica:index --queue

搜索

要执行搜索,请使用search方法。这使用闭包来搜索Elasticsearch类型,然后获取结果并从结果中添加一个where in查询。

search方法的第一个参数是一个闭包,它传递一个laralastica查询构建器的实例。

第二个参数是where in查询的列,默认为'id'。

第三个参数是一个布尔值,表示查询是否应按Elasticsearch结果的顺序排序。

Foo::search(function(Builder $query) {

	$query->matchAll();

}, 'foo', true)->get();

您还可以设置查询是否必须、应该或不必与您正在搜索的值匹配。

Foo::search(function(Builder $query) {

	$query->match('foo', 'bar')->must();
	$query->terms('bar', ['baz'])->should();
	$query->wildcard('baz', 'qux*', 1.0)->mustNot();

})->get();

您还可以在搜索前后链式调用任何Laravel查询构建器方法。

Foo::where('foo', 'bar')->search(function(Builder $query) {

	$query->match('foo', 'bar');

})->orderBy('baz')->get();

搜索软删除记录

默认情况下,laralastica将在模型被删除时删除Elasticsearch记录。

偶尔您可能想要搜索软删除的记录,为此,您在模型中实现SearchSoftDeletes特性,而不是实现Searchable特性。

use Illuminate\Database\Eloquent\Model;
use Michaeljennings\Laralastica\SearchSoftDeletes;

class Foo extends Model
{
	use SearchSoftDeletes;
}

这添加了两个新方法 - searchWithTrashedsearchOnlyTrashed

这两种方法都使用与搜索方法相同的参数,但searchWithTrashed将搜索软删除和非软删除的结果,而searchOnlyTrashed将只获取软删除的结果。

要仅搜索非软删除的结果,只需像往常一样使用search方法。

不使用可搜索特性进行搜索

您还可以在不使用可搜索特性的情况下使用Laralastica。为此,您可以通过其合同依赖注入类,使用提供的门面,或使用laralastica辅助方法。

class Foo
{
	public function __construct(Michaeljennings\Laralastica\Contracts\Laralastica $laralastica)
	{
		$this->laralastica = $laralastica;
	}

	public function foo()
	{
		$laralastica = Laralastica::search();
		$laralastica = laralastica();
	}
}

要运行新的查询,请使用search方法。它需要两个参数

  • 您要搜索的索引/索引
  • 要运行的查询
$laralastica->search('foo', function($query) {
	$query->matchAll();
});

要跨多个Elasticsearch索引进行搜索,只需将索引数组作为第一个参数传递。

$laralastica->search(['foo', 'bar], function($query) {
	$query->matchAll();
});

要获取分页的结果列表,请调用paginate方法并指定分页的数量。

$laralastica->paginate('foo', function($query) {
	$query->matchAll();
}, 15);

限制结果

默认情况下,结果将限制在laralastica.php配置文件中设置的尺寸。但是,您可以通过调用size方法来覆盖它。

$laralastica->search('foo', function($query) {
	$query->size(50);
});

偏移结果

您还可以通过调用from方法提供偏移量。

$laralastica->search('foo', function($query) {
	$query->from(10);
});

排序结果

默认情况下,我们按分数降序排序结果。您可以通过调用排序方法来覆盖此操作。

$laralastica->search('foo', function($query) {
    // Sort by id in ascending order
    $query->sort('id');
    // Sort by id in descending order
    $query->sort('id', 'desc');
    // Sort by multiple fields
    $query->sort([
        '_score',
        'id' => 'desc'
    ]);
});

查询

Elasticsearch查询由优秀的elastica包提供。

查询构建器上有一些预设查询,但您也可以创建Elastica查询的实例并将其传递。

可用查询

以下列出了可用查询。

每个查询都可以作为最后一个参数传递一个回调,这将允许您访问原始Elastica查询。

布尔查询

$laralastica->search('foo', function($query) {

    $query->bool(function($query) {
        $query->match('foo', 'bar');
    });

});

常见查询

$laralastica->search('foo', function($query) {

    $query->common('baz', 'qux', 1.0);
    $query->common('baz', 'qux', 1.0, function($commonQuery) {
        $commonQuery->setMinimumShouldMatch(5);
    });

});

存在查询

$laralastica->search('foo', function($query) {

    $query->exists('baz');

});

模糊查询

$laralastica->search('foo', function($query) {

    $query->fuzzy('baz', 'qux');
    $query->fuzzy('baz', 'qux', function($fuzzyQuery) {
        $fuzzyQuery->setFieldOption('fuzziness', 2);
    });

});

匹配查询

$laralastica->search('foo', function($query) {

    $query->match('baz', 'qux');
    $query->match('baz', 'qux', function($matchQuery) {
        $matchQuery->setFieldBoost('foo');
    });

});

匹配所有查询

$laralastica->search('foo', function($query) {

    $query->matchAll();

});

查询字符串查询

$laralastica->search('foo', function($query) {

    $query->queryString('testing');
    $query->queryString('testing', function($queryStringQuery) {
        $queryStringQuery->setDefaultField('foo');
    });

});

范围查询

$laralastica->search('foo', function($query) {

    $query->queryString('foo', ['gte' => 1, 'lte' => 20]);
    $query->queryString('foo', ['gte' => 1, 'lte' => 20], function($rangeQuery) {
        $rangeQuery->setParam('foo', ['gte' => 1, 'lte' => 20, 'boost' => 1]);
    });

});

正则表达式查询

$laralastica->search('foo', function($query) {

    $query->regexp('foo', 'testing');

});

项查询

$laralastica->search('foo', function($query) {

    $query->term(['foo' => 'bar']);
    $query->term(['foo' => 'bar'], function($termQuery) {
        $termQuery->setTerm('baz', 'qux', 2.0);
    });

});

项查询

$laralastica->search('foo', function($query) {

    $query->terms('foo', ['bar', 'baz']);
    $query->terms('foo', ['bar', 'baz'], function($query) {
        $query->setMinimumMatch(5);
    });

});

通配符查询

$laralastica->search('foo', function($query) {

    $query->wildcard('foo', 'bar');

});

过滤器

有时您可能想要运行一个查询来排除/包含记录,但又不希望查询影响分数。

您可以使用过滤器来做到这一点。

要添加过滤器,请调用filter方法并传递一个回调。回调将传递一个laralastica构建器实例作为第一个参数。

例如,如果只想搜索具有到期日期的记录,我们可以这样做。

$laralastica->search('foo', function($query) {
    $query->matchAll()
          ->filter(function($query) {
            $query->exists('due_date');
          });
});

分页结果

要获取分页的结果列表,请使用paginate方法并传递分页结果的数量。

$laralastica->paginate('foo', function($query) {

    $query->matchAll();

}, 15);

原始Elastica查询

要运行原始Elastica查询,创建查询实例并将其传递给query方法。

$laralastica->search('foo', function($query) {

    $match = new \Elastica\Query\Match();

    $query->query($match);

});

结果集合

search方法将返回结果集合的实例。这扩展了默认的Laravel集合,但也添加了一些laralastica特定的方法。

总命中数

获取查询匹配的总命中数。

$results = $laralastica->search('foo', function($query) { $query->matchAll() });

$results->totalHits();

最大分数

获取搜索匹配的最大分数。

$results = $laralastica->search('foo', function($query) { $query->matchAll() });

$results->maxScore();

耗时

获取执行Elasticsearch查询所花费的时间。

$results = $laralastica->search('foo', function($query) { $query->matchAll() });

$results->totalTime();