opencontent/occustomfind-ls

Opencontent 自定义搜索

安装量: 3,012

依赖: 0

建议者: 0

安全: 0

星标: 0

关注者: 6

分支: 1

开放问题: 0

类型:ezpublish-legacy-extension

2.7.0 2024-09-24 10:35 UTC

README

此扩展允许索引非 eZContentObject 的自定义内容到 Solr。它对于创建视图和对外部表格进行搜索非常有用。

安装

启用扩展。重新生成 autoloads。清除缓存。

使用示例

例如,想要索引一个存储在 csv 文件中的电话簿,但不打算将其作为 eZ 对象导入,而是想要能够对其进行搜索。

在 siteaccess 或 override 的 occustomfind.ini.append.php 中启用仓库

通过输入标识符和仓库的 PHP 类来启用。

[Settings]
AvailableRepositories[elenco_telefonico]=ElencoTelefonicoSearchableRepository

在创建仓库之前,我们首先创建一个代表电话簿元素的类

创建 ElencoTelefonicoSearchableObject

该类实现了 OCCustomSearchableObjectInterface,并代表电话簿中的一个元素

class ElencoTelefonicoSearchableObject implements OCCustomSearchableObjectInterface
{
    private $id;
    private $nome;
    private $cognome;
    private $numeriDiTelefono;
    private $note;

    /**
     * Il costruttore è liberamente definibile perché l'interfaccia non lo contempla.
     *
     * @param $id
     * @param $nome
     * @param $cognome
     * @param $numeriDiTelefono
     * @param $note
     */
    public function __construct($id, $nome, $cognome, $numeriDiTelefono, $note)
    {
        $this->nome = $nome;
        $this->cognome = $cognome;
        $this->numeriDiTelefono = $numeriDiTelefono;
        $this->note = $note;
    }

    /**
     * Questo meteodo deve resituire una stringa (bada bene non un numero) che identifica il documento univocamente in solr
     *
     * @return string
     */
    public function getGuid()
    {
        return return 'elenco-telefonico-' . $this->id;
    }

    /**
     * Questo metodo serve a definire i campi che solr deve indicizzare
     * Deve resituire un array di OCCustomSearchableFieldInterface per comodità conviene usare OCCustomSearchableField
     *
     * OCCustomSearchableField::create è una scorciatoia per
     * $field = new OCCustomSearchableField;
     * $field->setName($name)->setType($type)->isMultiValue($multiValue);
     *
     * @return OCCustomSearchableFieldInterface[]
     */
    public static function getFields()
    {
        return array(
            OCCustomSearchableField::create('id', 'int'),

            OCCustomSearchableField::create('cognome', 'string'),

            OCCustomSearchableField::create('nome', 'text'),

            // scorciatoia per isMultiValue vedi OCCustomSearchableField::setType
            OCCustomSearchableField::create('numeriDiTelefono', 'string[]'),

            OCCustomSearchableField::create('note', 'text'),
        );
    }

    /**
     * Restituisce il valore del campo presente in $field
     *
     * @param OCCustomSearchableFieldInterface $field
     *
     * @return mixed
     */
    public function getFieldValue(OCCustomSearchableFieldInterface $field)
    {
        if ($field->getName() == 'id'){
            return $this->id;

        }elseif ($field->getName() == 'cognome') {
            return $this->cognome;

        }elseif ($field->getName() == 'nome') {
            return $this->nome;

        }elseif ($field->getName() == 'numeriDiTelefono') {
            return $this->numeriDiTelefono;

        }elseif ($field->getName() == 'note') {
            return $this->note;
        }

        return null;
    }

    /**
     * Restiruisce la rappresentazione dell'oggetto come array
     *
     * @return array
     */
    public function toArray()
    {
        return array(
            'id' => $this->id,
            'cognome' => $this->cognome,
            'nome' => $this->nome,
            'numeriDiTelefono' => $this->numeriDiTelefono,
            'note' => $this->note,
        );
    }

    /**
     * Crea l'oggetto a partire da un array
     *
     * @param $array
     *
     * @return ElencoTelefonicoSearchableObject
     */
    public static function fromArray($array)
    {
        extract($array);
        return new ElencoTelefonicoSearchableObject($id, $nome, $cognome, $numeriDiTelefono, $note);
    }

}

然而,如果您已经有了对象的键值数组表示,则可以使用抽象类 OCCustomSearchableObjectAbstract。这将更快

class ElencoTelefonicoSearchableObject extends OCCustomSearchableObjectAbstract
{

    public function getGuid()
    {
        return 'elenco-telefonico-' . $this->attributes['id'];
    }

    public static function getFields()
    {
        return array(
            OCCustomSearchableField::create('id', 'int'),
            OCCustomSearchableField::create('cognome', 'string'),
            OCCustomSearchableField::create('nome', 'text'),
            OCCustomSearchableField::create('numeriDiTelefono', 'string[]'),
            OCCustomSearchableField::create('note', 'text'),
        );
    }
}

创建 ElencoTelefonicoSearchableRepository

该类必须实现 OCCustomSearchableRepositoryInterface 接口,但所有脏活都已经由 OCCustomSearchableRepositoryAbstract 类完成,因此为了避免重复工作,我们最好扩展它,同时也要查看一下代码...

class ElencoTelefonicoSearchableRepository extends OCCustomSearchableRepositoryAbstract
{
    private $csvFile;

    private $csvRows;

    /**
     * Nel costruttore salvo il nome del file csv da usare
     * Questo è solo un esempio, immagina che il nome del file csv venga caricato tramite ini
     * Tuttavia il costruttore non può avere argomenti (non abbiamo DependyInjection qui...)
     */
    public function __construct()
    {
        $this->csvFile = 'elenco_telefonico.csv';
    }

    /**
     * Parsa il file e restituisce le righe
     * @return array
     */
    private function getCsvRows()
    {
        if ($this->csvRows === null) {
            // il metodo parseFile deve parsare il file e restuire un array di righe
            // in questo esempio non è implementato
            $this->csvRows = $this->parseFile($this->csvFile);
        }

        return $this->csvRows;
    }

    /**
     * Questo metodo deve restituire la stringa dell'identificativo del repository, meglio usare quello definito nella chiave dell'ini
     */
    public function getIdentifier()
    {
        return 'elenco_telefonico';
    }

    /**
     * Questo campo deve restituire il FQCN della classe che si vuole indicizzare (creata sopra)
     */
    public function availableForClass()
    {
        return ElencoTelefonicoSearchableObject::class;
    }

    /**
     * Ritorna il numero totale di oggetti indicizzabili
     * Vedi il file bin/php/updatecustomsearchindex.php
     */
    public function countSearchableObjects()
    {
        return count($this->getCsvRows());
    }

    /**
     * Restiruisce un array di ElencoTelefonicoSearchableObject
     * Vedi il file bin/php/updatecustomsearchindex.php
     *
     * Il repository deve essere paginato: in questo esempio viene simulata la paginazione
     *
     * I metodi richiamati non sono implemetati
     *
     * @param int $limit
     * @param int $offset
     *
     * @return ElencoTelefonicoSearchableObject[]
     */
    public function fetchSearchableObjectList($limit, $offset)
    {
        $data = array();
        foreach($this->getCsvRows() as $index => $row) {

            if ($index < $offset){
                continue;
            }

            if (count($data) == $limit) {
                break;
            }

            $data[] = new ElencoTelefonicoSearchableObject(
                $this->getIdFromRow($row),
                $this->getNomeFromRow($row),
                $this->getCognomeFromRow($row),
                $this->getNumeriDiTelefonoFromRow($row),
                $this->getNoteFromRow($row)
            );

            // se invece usiamo l'approccio ad array si farà qualcosa di simile
            // $data[] = new ElencoTelefonicoSearchableObject($this->getArrayFromRow($row));
        }

        return $data;
    }

}

通过脚本索引仓库

php extension/occustomfind/bin/php/updatecustomsearchindex.php -sbackend --repository=elenco_telefonico

执行搜索

要使用 PHP 执行搜索,需要使用仓库的 find 方法,并传递一个 OCCustomSearchParameters 类的对象

结果是包含以下值的数组

  • totalCount:搜索中考虑的所有 ElencoTelefonicoSearchableObject 的总数
  • searchHits:ElencoTelefonicoSearchableObject 的数组
  • facets:键为字段,值为名称哈希的计数的数组
$parameters = OCCustomSearchParameters::instance()

    // la ricerca libera funziona sui campi di tipo text, se sono string occorre cercare per tutta la stringa
    ->setQuery('amico di Topolino')

    // i filtri accettano array o array di array come i filters di eZFind
    // i nomi dei campi sono quelli definiti nel ElencoTelefonicoSearchableObject::getFields
    ->setFilters(array(
        array(
            'and',
            array('nome' => 'Paolino'),
            array('cognome' => 'Paperino')
        )
    ))

    // anche nelle faccette come nei filtri i nomi dei campi sono quelli definiti nel ElencoTelefonicoSearchableObject::getFields
    ->setFacets(array(array('field' => 'cognome')))

    // ordinamento
    // come sopra per i nomi dei campi
    ->setSort(array('cognome' => 'asc', 'nome' => 'asc'))

    // limite
    ->setLimit(10)

    // offset
    ->setOffset(0);

$repository = new ElencoTelefonicoSearchableRepository();
$result = $repository->find($parameters);

要执行 HTTP 上的搜索,需要使用 customfind 模块,目前它有点限制,因为尚未处理 'or' 过滤器

http://www.example.com/debug/customfind/elenco_telefonico?query=amico di Topolino&filters[nome]=Paolino&filters[cognome]=Paperino&facets[]=cognome&sort[cognome]=asc&sort[nome]=asc&limit10&offset=0

通过脚本重新索引仓库

php extension/occustomfind/bin/php/updatecustomsearchindex.php -sbackend --repository=elenco_telefonico --clean

通过脚本清空仓库

php extension/occustomfind/bin/php/trucate.php -sbackend --repository=elenco_telefonico

通过脚本索引所有仓库

php extension/occustomfind/bin/php/updatecustomsearchindex.php -sbackend --clean

通过脚本重新索引所有仓库

php extension/occustomfind/bin/php/updatecustomsearchindex.php -sbackend --clean

通过脚本清空所有仓库

php extension/occustomfind/bin/php/truncate.php -sbackend

虚拟类

在 occustomfind.ini 中有两个示例仓库,它们按类型索引了 10 个内容。为了测试它们,需要启用它们