heyday / silverstripe-elastica
为 SilverStripe DataObjects 提供 Elastic Search 集成,使用 Elastica
Requires
- php: >=8.1
- elasticsearch/elasticsearch: >=7.3.0
- ruflin/elastica: ^7
- silverstripe/framework: ^5
- symbiote/silverstripe-queuedjobs: *
Requires (Dev)
- phpunit/phpunit: ^9.5
- squizlabs/php_codesniffer: ^3.4
This package is auto-updated.
Last update: 2024-08-28 22:35:02 UTC
README
简化了使用 ElasticSearch 进行 SilverStripe CMS 搜索和索引的过程。我们使用 Elastica 来处理与弹性搜索服务器的通信。
此模块使得在不限制 Elastica 中发现的功能的情况下使用 ElasticSearch 变得很容易。基本上,所有可以单独使用 Elastica 完成的事情都可以与这个模块一起完成。
此模块取代了 Symbiote 的 Elastica 模块,该模块只支持到 SilverStripe 3。
功能
- 使用 Elastica 与 ElasticSearch 服务器通信
- 使用 PSR/Log 接口进行日志记录(可选)
- 使用 YAML 配置来索引数据对象和页面
- 可以处理索引的 ElasticSearch 文档中的 has_many、many_many 和 has_one 关系
- 可以处理相关数据对象的失效和重新索引
- 可以处理仅存在于对象实例中而不是数据库中的自定义字段
- 从对应 SilverStripe 模型中定义的数据库字段类型推断 ElasticSearch 文档字段类型
兼容性
此版本应与所有 7.0 及以上版本的 ElasticSearch 兼容。可能与 6.x 版本的 Elasticsearch 一起工作。此版本需要 SilverStripe 4.x
如果您需要与更早版本的 Elasticsearch (2.x) 和 SS (3.x) 一起工作,请尝试此模块的 1.0 版本
安装
$ composer require heyday/silverstripe-elastica
用法
Elastica 服务配置示例
mysite/_config/search.yml
Heyday\Elastica\ElasticaService: # Example of customising the index config on the elastic search server (completely optional). index_config: settings: analysis: analyzer: default: type: custom tokenizer: standard filter: - lowercase - stemming_filter filter: stemming_filter: type: snowball language: English --- Only: environment: dev --- SilverStripe\Core\Injector\Injector: Elastica\Client: constructor: - host: localhost # hostname of the elastic search server port: 9200 # port number of the elastic search server Heyday\Elastica\ElasticaService: constructor: - "%$Elastica\Client" - "name-of-index" # name of the index on the elastic search server - "%$Logger" # your error logger (must implement psr/log interface) - "64MB" # increases memory limit while indexing
索引配置示例
mysite/_config/search.yml
# PageTypes Your\Namespace\Page: extensions: - Heyday\Elastica\Searchable indexed_fields: &page_defaults - Title - MenuTitle - Content - MetaDescription Your\Namespace\SpecialPageWithAdditionalFields: extensions: - Heyday\Elastica\Searchable # only needed if this page does not extend the 'Page' configured above indexed_fields: <<: *page_defaults - BannerHeading - BannerCopy - SubHeading Your\Namespace\SpecialPageWithRelatedDataObject: extensions: - Heyday\Elastica\Searchable indexed_fields: <<: *page_defaults - RelatedDataObjects: type: nested relationClass: App\DataObjects\Tags # Will be pulled from has_many / many_many, but you can specify it here too Your\Namespace\RelatedDataObject: extensions: - Heyday\Elastica\Searchable indexed_fields: - Title - SomeOtherField dependent_classes: - SpecialPageWithRelatedDataObject # invalidates the index for SpecialPageWithRelatedDataObject when a RelatedDataObject is updated/created
自定义字段索引配置示例
mysite/_config/search.yml
# PageTypes Your\Namespace\Page: extensions: - Heyday\Elastica\Searchable indexed_fields: - Title - SomeOtherField - TitleAlias: type: text field: Title # You can specify a custom internal field value with 'field' - SomeCustomFieldSimple: type: text - SomeCustomFieldComplicatedConfig: type: text analyzer: nGram_analyser # Must reference analyzer defined on index_config search_analyzer: whitespace_analyser # Must reference analyzer defined on index_config store: true
mysite/code/PageTypes/Page.php
<?php class Page extends SiteTree { public function getSomeCustomFieldSimple() { return 'some dynamic text or something'; } public function getSomeCustomFieldComplicatedConfig() { return 'the config does not have anyting to do with me'; } }
简单搜索控制器配置/实现示例
mysite/_config/search.yml
SearchController: properties: SearchService: "%$Heyday\Elastica\ElasticaService"
mysite/code/Controllers/SearchController.php
<?php class SearchController extends Page_Controller { /** * @var array */ private static $allowed_actions = [ 'index' ]; /** * @var \Heyday\Elastica\ElasticaService */ protected $searchService; /** * Search results page action * * @return HTMLText */ public function index() { return $this->renderWith(['SearchResults', 'Page']); } /** * @param \Heyday\Elastica\ElasticaService $searchService */ public function setSearchService(\Heyday\Elastica\ElasticaService $searchService) { $this->searchService = $searchService; } /** * @return bool|\Heyday\Elastica\PaginatedList */ public function Results() { $request = $this->getRequest(); if ($string = $request->requestVar('for')) { $query = new \Elastica\Query\BoolQuery(); $query->addMust( new \Elastica\Query\QueryString(strval($string)) ); $results = $this->searchService->search($query); return new \Heyday\Elastica\PaginatedList($results, $request); } return false; } /** * Query all Page fields and RelatedObjects nested fields. * * @return bool|\SilverStripe\ORM\PaginatedList */ public function ResultsWithRelatedObjects() { $request = $this->getRequest(); if ($string = $request->requestVar('for')) { $queryString = new \Elastica\Query\QueryString(strval($string)); $boolQuery = new \Elastica\Query\BoolQuery(); $nestedQuery = new \Elastica\Query\Nested(); $nestedQuery->setPath('RelatedDataObjects'); $nestedQuery->setQuery($queryString); $boolQuery->addShould($queryString); $boolQuery->addShould($nestedQuery); $results = $this->searchService->search($boolQuery); return new \SilverStripe\ORM\PaginatedList($results, $request); } return false; } /** * @return mixed */ public function SearchString() { return Convert::raw2xml($this->getRequest()->requestVar('for')); } }
重新索引
要运行 Elastica 的完整重新索引,请使用
./vendor/bin/sake dev/tasks/ElasticaReindexTask
使用队列
您可以使用队列来在后台运行重新索引过程。
我们使用 silverstripe-queuedjobs (https://github.com/symbiote/silverstripe-queuedjobs) 并创建了一个重新索引的任务。
要开启队列,您需要以下配置
SilverStripe\Core\Injector\Injector: Heyday\Elastica\Searchable: properties: queued: true
您还需要设置一个 cronjob(我知道这不太像队列...)
每分钟运行队列中的任务
*/1 * * * * php /path/to/silverstripe/framework/cli-script.php dev/tasks/ProcessJobQueueTask
并且为了清理任务,运行一次(然后它将自动添加为每天运行一次)
framework/sake dev/tasks/CreateQueuedJobTask?name=Symbiote\QueuedJobs\Jobs\CleanupJob