cyber-duck/silverstripe-searchly

SilverStripe的Elastic Search集成

安装数: 16,084

依赖者: 0

建议者: 0

安全性: 0

星标: 2

关注者: 6

分支: 4

类型:silverstripe-vendormodule

4.4.0 2022-11-29 11:48 UTC

README

此软件包可以为运行在本地环境、服务器(如AWS)或Elastic Search服务(如Searchly)上的任何Elastic Search实例添加索引DataObjects的能力。

Latest Stable Version Latest Unstable Version Total Downloads License

作者: Andrew Mc Cormack

适用于SilverStripe 4.*

安装

将以下内容添加到您的composer.json文件中,并运行/dev/build?flush=all

{  
    "require": {  
        "cyber-duck/silverstripe-searchly": "4.1.*"
    }
}

配置

有关配置选项,请参阅_config/searchly.yml

设置您的Elastic Search端点

在.env文件中添加SEARCHLY_BASE_URI变量,并使用任何有效的ES端点(AWS、searchly等)

SEARCHLY_BASE_URI="https://site:{api-key}@xyz.searchly.com" - 

或者对于本地docker ES实例或类似实例

SEARCHLY_BASE_URI="http://es:9200"

设置可索引的DataObject字段和关系

模型及其关系可以作为一个可搜索的对象一起索引。要索引字段及其关系,您可以在DataObject上使用searchable_*配置数组。

以下示例中,Tags和ContentBlocks关系需要它们自己的searchable_*配置。在索引时,这些关系将被遍历并创建嵌套对象。

private static $searchable_db = [
    'Title',
    'Content'
];

private static $searchable_has_many = [
    'Tags'
];

private static $searchable_many_many = [
    'ContentBlocks'
];

对搜索索引执行操作

创建一个搜索索引实例,您可以访问更改和操作搜索索引的功能,如创建新的索引、添加/删除记录等。

$index = new SearchIndex(
    'pages', // the index name, can be hard coded or better to pull from a .env var
    'pages', // the searchly index _type
    [Page::class] // an array of models to index, can be pages or non pages
);

createIndex($mappings = [], $settings = [])

在您的搜索索引实例上调用此方法将构建ES端点索引。有关映射和设置的完整配置,请参阅Elastic Search文档。

$mappings = [
    'Created' => [
        'type' => 'date',
    ],
    'LastEdited' => [
        'type' => 'date',
    ],
    'ClassName' => [
        'type' => 'keyword',
    ],
    'Title' => [
        'type' => 'text',
        'boost' => 100,
    ],
    'Link' => [
        'type' => 'text',
        'index' => false,
    ]
];

$settings = [
    'analysis' => [
        'analyzer' => [
            'default' => [
                'type' => 'english',
            ]
        ]
    ]
];
            
$index->createIndex($mappings, $settings);

deleteIndex()

此方法将完全从您的ES端点删除搜索索引。

$index->deleteIndex();

resetIndex($mappings = [], $settings = [])

此方法将调用deleteIndex()然后调用createIndex()。请确保传递与createIndex()相同的映射和设置配置;

$index->resetIndex($mappings, $settings);

index(array $filters = [])

此方法将推送所有模型到您在创建搜索索引实例时指定的ES端点索引。

以下示例中,调用index将遍历所有页面和文件模型,创建它们的JSON表示,并将它们推送到ES端点索引。

$index = new SearchIndex(
    'models', // the index name, can be hard coded or better to pull from a .env var
    'models', // the searchly index _type
    [
        Page::class,
        File::class
    ]
);
$index->index();

如果您希望从索引中排除某些模型,还可以应用过滤器。

$index->index([
    Page::class => [
        'ClassName:not' => ErrorPage::class,
    ],
    File::class => [
        'ClassName:not' => Folder::class,
    ],
]);

您还可以通过调用index然后getRecords()来查看发送到ES端点索引的所有数据。这将返回一个JSON对象数组。

$index->index([...])->getRecords();

indexRecord(DataObject $record)

将单个数据对象添加到ES端点索引

$index->indexRecord(
    Page::get()->find('ID', 1)
);

removeRecord(DataObject $record)

从ES端点索引中删除单个数据对象

$index->removeRecord(
    Page::get()->find('ID', 1)
);

创建一个索引任务

创建索引的最简单方法是创建一个SilverStripe任务并运行它以创建/重建所有索引

use CyberDuck\Searchly\Index\SearchIndex;
use SilverStripe\Assets\File;
use SilverStripe\Dev\BuildTask;

class SearchIndexTask extends BuildTask 
{
    protected $enabled = true;

    protected $title = "Searchly Pages index task";

    protected $description = "Indexes all site pages for use in searchly";

    public function run($request)
    {
        $mappings = [
            ... // your configuration
        ];

        $settings = [
            ... // your configuration
        ];

        $index = new SearchIndex(
            'pages', // the index name, can be hard coded or better to pull from a .env var
            'pages', // the searchly index _type
            [Page::class] // an array of models to index, can be pages or non pages
        );
        $index->resetIndex($mappings, $settings);
        $index->index();

        $index = new SearchIndex(
            'files', // the index name, can be hard coded or better to pull from a .env var
            'files', // the searchly index _type
            [File::class] // an array of models to index, can be pages or non pages
        );
        $index->resetIndex($mappings, $settings);
        $index->index();
    }
}

如果您在索引大量模型时遇到PHP超时,可以尝试增加执行时间

    public function run($request)
    {
        ini_set('max_execution_time', 300);

        $index = new SearchIndex(...

执行搜索

要执行搜索查询,请创建一个新的SearchQuery实例,并将搜索词和索引名称注入到构造函数中。

use CyberDuck\Searchly\Index\SearchQuery;

$query = new SearchQuery(
    $term, // the search term
    'pages' // the index name, can be hard coded or better to pull from a .env var
);

配置您的搜索查询

您可以控制返回的结果数量。对于非常大的数据集非常有用。

$query->setSize(50);

您还可以控制AND / OR匹配

$query->setOperator('OR'); 

还有一个自定义方法可以设置analyze_wildcard配置为true / false

$query->setWildcard(true);

或者,您可以为任何情况构建自己的高度复杂的配置。

$query->setConfig('sort', [['Created' => 'desc']]);
$query->setConfig('query', [
    'bool' => [
        'must' => [
            [
                'query_string' => [
                    'query' => '*'.$escapedterm.'*',
                    'analyze_wildcard' => true,
                    'default_operator' => 'OR',
                ]
            ]
        ]
    ]
]);

获取搜索结果

要返回匹配的模型ID数组,可以调用getIDs()方法。

$ids = $query->getIDs();

要返回匹配的对象数组,可以调用getHits()方法。

$objects = $query->getHits();

通过在SearchQuery实例上调用setHighlight()并在调用getHighlights(),也可以返回高亮/匹配的文本。

$query->setHighlight(true);

$highlights = $query->getHighlights();

要返回完整的ES端点响应对象,可以在查询对象上调用getResponse()方法。这对于调试很有用。

$response = $query->getResponse();