且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

自定义网站搜索,以便根据其子级的内容返回父类型

更新时间:2023-10-14 15:50:16

一种可行的解决方案是在子级而不是项本​​身上重新索引子级的searchableText(连接所有子级的searchableText).>

您的新searchableText索引可能如下所示:

 @indexer(IYourContainerType)
def SearchableText(obj):
    searchable_text = obj.SearchableText()

    for item in obj.getFolderContents({'portal_type': 'File'}, full_object=True):
        searchable_text += item.SearchableText()
    return searchable_text
 

现在您必须预订一些事件,因为容器的SearchableText需要根据容器中的更改自动更新.

处理以下情况:

  1. 某些东西已添加到容器中
  2. 已从容器中取出物品
  3. 容器中的某些内容已修改

Docu for Plone中的事件

事件处理程序可能看起来像这样:

 def reindex_container(obj, event):
    parent = aq_parent(aq_inner(obj))

    if not IYourContainerType.providedBy(parent):
        return

    catalog = getToolByName(obj, 'portal_catalog')
    # Only reindex existing brains! The parent may be just
    # deleted, we should not put it back in the catalog.
    parent_path = '/'.join(parent.getPhysicalPath())
    if catalog.getrid(parent_path) is not None:
        parent.reindexObject()
 

可能您需要单独处理MOVE.

I have a dexterity content type which is folderish and I would like to have it show up in search results based on it's child's content (pdfs etc). Is this possible, where and how would this be achieved?

One possible solution is to reindex the searchableText of the children on the parent and not on the item itself (concatenate the searchableText of all children).

Your new searchableText Index could look like this:

@indexer(IYourContainerType)
def SearchableText(obj):
    searchable_text = obj.SearchableText()

    for item in obj.getFolderContents({'portal_type': 'File'}, full_object=True):
        searchable_text += item.SearchableText()
    return searchable_text

Now you have to subscribe some events, because the SearchableText of the container needs to be updated automatically on changes in the container.

Handle if:

  1. something is added to the Container
  2. something is removed from the container
  3. something is modified in the Container

Docu for Events in Plone

The eventhandler could look like this:

def reindex_container(obj, event):
    parent = aq_parent(aq_inner(obj))

    if not IYourContainerType.providedBy(parent):
        return

    catalog = getToolByName(obj, 'portal_catalog')
    # Only reindex existing brains! The parent may be just
    # deleted, we should not put it back in the catalog.
    parent_path = '/'.join(parent.getPhysicalPath())
    if catalog.getrid(parent_path) is not None:
        parent.reindexObject()

Probably you need to handle MOVE separately.