haunt-jonathan / heyday-silverstripe-elastica
使用Elastica为SilverStripe DataObjects提供Elastic Search集成
Requires
- php: >=7.4
- elasticsearch/elasticsearch: >=7.3.0
- ruflin/elastica: ^7
- symbiote/silverstripe-queuedjobs: ^4
Requires (Dev)
- phpunit/phpunit: ^9.5
- squizlabs/php_codesniffer: ^3.4
This package is not auto-updated.
Last update: 2024-10-01 03:59:15 UTC
README
该模块简化了使用ElasticSearch进行SilverStripe CMS搜索和索引的过程。我们使用Elastica来处理与ElasticSearch服务器通信的所有繁重任务。
此模块使您能够轻松地在SilverStripe中使用ElasticSearch,同时不会限制Elastica中的任何功能。基本上,任何仅使用Elastica即可完成的事情,都可以与该模块一起完成。
此模块取代了Symbiote的Elastica模块,该模块仅支持SilverStripe 3。
功能
- 使用Elastica与ElasticSearch服务器通信
- 使用PSR/Log接口进行日志记录(可选)
- 使用YAML配置来索引数据对象和页面
- 可以处理索引的ElasticSearch文档中的has_many、many_many和has_one关系
- 可以处理相关数据对象的失效和重新索引
- 可以处理作为对象实例一部分但不在数据库中的自定义字段
- 从相应的SilverStripe模型中定义的数据库字段类型推断ElasticSearch文档字段类型
兼容性
此版本应与所有ElasticSearch 7.0及以上版本兼容。可能适用于Elasticsearch 6。此版本需要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