Silverstripe FulltextSearchable将表Engines转换为MyIsam

时间:2017-04-07 10:05:39

标签: php silverstripe

为了添加SiteSearch功能,当我在Silverstripe中启用FullTextSearchable时,默认情况下它会将Page表转换为MyISAM,但我需要保留表InnoDB。 我正在使用MySQL版本> 5.6(因此,它确实支持FullText)

2 个答案:

答案 0 :(得分:7)

正如您所指出的,自MySQL版本5.6以来InnoDB确实支持全文搜索,但框架附带的MySQLSchemaManager会阻止您将InnoDB用于定义了全文索引的表。也许你可以在GitHub上提出一个问题。您可以创建自己的SchemaManager而不受此限制(通过扩展MySQLSchemaManager并覆盖alterTable()):

# Compare this to https://github.com/silverstripe/silverstripe-framework/blob/3.5/model/connect/MySQLSchemaManager.php#L100
class MyCustomSchemaManager extends MySQLSchemaManager
{

    public function alterTable($tableName, $newFields = null, $newIndexes = null, $alteredFields = null,
                               $alteredIndexes = null, $alteredOptions = null, $advancedOptions = null
    ) {
        if ($this->isView($tableName)) {
            $this->alterationMessage(
                sprintf("Table %s not changed as it is a view", $tableName),
                "changed"
            );
            return;
        }
        $alterList = array();

        if ($newFields) {
            foreach ($newFields as $k => $v) {
                $alterList[] .= "ADD \"$k\" $v";
            }
        }
        if ($newIndexes) {
            foreach ($newIndexes as $k => $v) {
                $alterList[] .= "ADD " . $this->getIndexSqlDefinition($k, $v);
            }
        }
        if ($alteredFields) {
            foreach ($alteredFields as $k => $v) {
                $alterList[] .= "CHANGE \"$k\" \"$k\" $v";
            }
        }
        if ($alteredIndexes) {
            foreach ($alteredIndexes as $k => $v) {
                $alterList[] .= "DROP INDEX \"$k\"";
                $alterList[] .= "ADD " . $this->getIndexSqlDefinition($k, $v);
            }
        }

        $dbID = self::ID;
        if ($alteredOptions && isset($alteredOptions[$dbID])) {
            $this->query(sprintf("ALTER TABLE \"%s\" %s", $tableName, $alteredOptions[$dbID]));
            $this->alterationMessage(
                sprintf("Table %s options changed: %s", $tableName, $alteredOptions[$dbID]),
                "changed"
            );
        }

        $alterations = implode(",\n", $alterList);
        $this->query("ALTER TABLE \"$tableName\" $alterations");
    }

}

然后您可以使用Injector来使用自定义类:

# Config.yml
Injector:
  MySQLSchemaManager:
    class: MyCustomSchemaManager

您现在应该能够使用静态create_table_options强制InnoDB引擎,并通过indexes静态创建全文索引。

示例:

# SomePage.php    

/**
 * Force InnoDB database engine.
 *
 * @var array
 */
private static $create_table_options = [
    'MySQLDatabase' => 'ENGINE=InnoDB'
];

/** 
 * Define what fulltext indexes to create.
 *
 * @var array
 */
private static $indexes = [
    'SearchFields' => [
        'type' => 'fulltext',
        'name' => 'SearchFields',
        'value' => '"MyField", "Tags"',
    ]
];

答案 1 :(得分:0)

全文搜索仅适用于MyISAM。这是MyISAM优于InnoDB的主要优势之一。相关:https://dba.stackexchange.com/questions/1/what-are-the-main-differences-between-innodb-and-myisam