10. CubicWeb中的全文索引

当属性标记为 fulltext-indexable 在数据模型中,CubicWeb将自动触发挂钩以更新内部全文索引(即 appears SQL表)每次修改此属性时。

CubicWeb还提供 db-rebuild-fti 按需重新生成整个全文的命令:

cubicweb@esope~$ cubicweb db-rebuild-fti my_tracker_instance

还可以为给定的一组实体类型重新生成全文索引:

cubicweb@esope~$ cubicweb db-rebuild-fti my_tracker_instance Ticket Version

在上面的示例中,只有实体类型的全文索引 TicketVersion 将被重建。

10.1. 标准FTI工艺

考虑实体类型 ET ,默认的 fti 过程是为了:

  1. 获取类型的所有实体 ET

  2. 对于每个实体,使其适应 IFTIndexable (见 IFTIndexableAdapter

  3. 调用 get_words() 在应该返回字典的适配器上 重量 > 单词表 如预期 index_object() .每个属性值的标记化技术是由 tokenize() .

IFTIndexableAdapter 更多文档。

10.2. 山药和 fulltext_container

在数据模型中,可以指示为实体类型定义的全文索引属性将用于索引实体本身,而不是相关实体。这对于复合实体尤其有用。让我们来看一下CubicWeb中定义的基本模式(简化版)(请参见 cubicweb.schemas.base ):

class CWUser(WorkflowableEntityType):
    login     = String(required=True, unique=True, maxsize=64)
    upassword = Password(required=True)

class EmailAddress(EntityType):
    address = String(required=True,  fulltextindexed=True,
                     indexed=True, unique=True, maxsize=128)


class use_email_relation(RelationDefinition):
    name = 'use_email'
    subject = 'CWUser'
    object = 'EmailAddress'
    cardinality = '*?'
    composite = 'subject'

上面的模式说明 CWUserEmailAddress 以及 address 领域 EmailAddress 是全文索引。因此,在应用程序中,如果使用全文搜索查找电子邮件地址,CubicWeb将返回 EmailAddress 本身。但是我们要索引的对象更可能是 CWUserEmailAddress 本身。

实现这一点的最简单方法是标记 use_email 数据模型中的关系:

class use_email(RelationType):
    fulltext_container = 'subject'

10.3. 自定义获取实体的方式 db-rebuild-fti

db-rebuild-fti 将调用 cw_fti_index_rql_limit() 实体类型的类方法。

10.4. 定制 get_words()

您还可以通过提供自己的FTI流程来定制FTI流程。 get_words() 实施:

from cubicweb.entities.adapters import IFTIndexableAdapter

class SearchIndexAdapter(IFTIndexableAdapter):
    __regid__ = 'IFTIndexable'
    __select__ = is_instance('MyEntityClass')

    def fti_containers(self, _done=None):
        """this should yield any entity that must be considered to
        fulltext-index self.entity

        CubicWeb's default implementation will look for yams'
        ``fulltex_container`` property.
        """
        yield self.entity
        yield self.entity.some_related_entity


    def get_words(self):
        # implement any logic here
        # see http://www.postgresql.org/docs/9.1/static/textsearch-controls.html
        # for the actual signification of 'C'
        return {'C': ['any', 'word', 'I', 'want']}