Liferay6.2:分片搜索和自定义查询过滤

Faceted Search and Customized Search Filtering - 分片搜索和自定义查询过滤

Faceted search(分片搜索)是一种搜索机制,它允许通过对搜索查询的结果应用一组过滤器来缩小搜索结果。 Liferay的Search portlet支持分片搜索。 其默认配置包含多个分片(facet),包括站点(Site),Asset Type,标记(Tag),类别(Category),文件夹(Folder),用户(User)和修改日期(Modified Date)。 使用Liferay的Search portlet执行搜索时,将显示结果集。 你可以通过单击一个或多个facet来应用搜索过滤器(search filter)优化搜索。 例如,默认情况下,Search portlet显示来自任何站点的结果。 在Search Portlet中,你可以单击特定站点的名称以过滤搜索,以仅显示所选站点的结果。 除了在Search portlet中使用分片搜索外,Liferay还在整个门户网站的其他位置透明地使用分片搜索。

在本教程中,你将学习如何在Liferay的Search portlet中创建自定义构面facets并对其进行配置。 你还将学习如何使用Liferay的search API来创建自定义搜索过滤器,而这些搜索过滤器不适合作为构面facets实现。 在继续之前,请确保您熟悉以下术语:

  • factes 方面:factes是与特定索引字段有关信息的组合:其术语(terms)和出现频率(frequencies)。facets通常以相关字段fields命名。
  • frequency 频率 :给定术语(terms)出现在一组文档中的次数称为术语频率(term’s frequency)。
  • term result list 术语结果列表 :特定字段的术语列表及其频率称为术语结果列表。换句话说,术语结果列表(term result list)是关于特定方面(facets)的信息的列表。
  • frequency threshold 频率阈值 :有些方面(facets)有一个称为频率阈值(frequency threshold)的属性。此值表示术语在术语结果列表中显示所需的最小频率。例如,如果方面的频率阈值设置为3,则仅出现两次的术语将不会出现在术语结果列表中。
  • max terms 最大术语 :有些方面有一个名为max terms的属性。此值表示术语结果列表中包含的最大术语数,而不管实际为方面找到多少匹配项。使用max terms属性可以控制搜索结果的数量,以便用户不会被太多信息所淹没。
  • order 顺序 :order属性决定使用术语结果列表的默认顺序。有两种可能的模式:Order Hits Descending或Order Value Ascending。第一个,Hits降序,意味着结果将按照频率降序排序。第二个,字段值升序,意味着结果将按字段值(比如按term)升序排序。当存在重复时,两种模式都回退到另一种模式作为辅助排序方式。这就意味着具有相同频率的许多术语会按值排序。
  • range 范围:范围range定义了一个区间,在该区间内对所有匹配术语的频率求和。这意味着,如果方面定义了2008年到2010年之间的createDate字段的术语范围(range term),并且在2012年到2014年之间定义了另一个术语范围,则创建时间在指定范围之一的所有匹配文档将作为该范围的总和返回。因此,您可能会在第一个范围内找到7个文档,在第二个范围内找到18个文档。范围(Range)不能与多值字段一起使用。

Configuring Custom Facets - 配置自定义方面

在Liferay中有两种方法可以为搜索配置自定义方面(facets):

  1. 在Liferay的Search portlet JSON配置中配置自定义方面(facets)。
  2. 使用Liferay的search API以编程方式创建方面并将其添加到search context中。

使用JSON定义设置方面配置是最灵活的解决方案,因为可以在运行时动态更改配置。 但是,此选项仅在Liferay的Search portlet中可用。 以编程方式将facet添加到search context允许开发人员严格控制搜索的使用方式。 自定义Liferay portlet的开发人员可以使用此选项。

假设你需要为用户提供仅在Liferay中搜索图像的方法。 你可以在Liferay的Search portlet中轻松配置自定义方面(facets)以实现此目的。 要将Search portlet配置为仅搜索图像,请打开Search portlet的“配置(Configuration)”窗口。 将以下两个facets添加到其JSON配置中:

{
        "displayStyle": "asset_entries",
        "static": true,
        "weight": 1.5,
        "order": "OrderHitsDesc",
        "data": {
                "values": [
                        "com.liferay.portlet.documentlibrary.model.DLFileEntry"
                ],
                "frequencyThreshold": 0
        },
        "className": "com.liferay.portal.kernel.search.facet.AssetEntriesFacet",
        "label": "asset-type",
        "fieldName": "entryClassName"
},
{
        "displayStyle": "asset_entries",
        "static": true,
        "weight": 1.5,
        "order": "OrderHitsDesc",
        "data": {
                "values": [
                        "bmp", "gif", "jpeg", "jpg", "odg", "png", "svg"
                ],
                "frequencyThreshold": 0
        },
        "className": "com.liferay.portal.kernel.search.facet.MultiValueFacet",
        "label": "images",
        "fieldName": "extension"
}

要了解如何配置Liferay的Search portlet,包括对此示例的说明,请参阅Search portlet documentation。

Liferay中的分片搜索不仅限于Liferay的Search portlet。如果要为自定义Liferay portlet实现搜索功能,仍可以通过以编程方式创建facets并将其添加到search context来实现分片搜索。 Liferay提供了几个facets实现类,开发人员可以实例化并用于自定义portlet开发。 这些facet实现类位于Liferay的com.liferay.portal.kernel.search.facet包。 它们包括:

  • SimpleFacet
  • MultiValueFacet
    • AssetEntriesFacet
    • ScopeFacet
  • RangeFacet
    • ModifiedFacet

SimpleFacet,MultiValueFacet和RangeFacet扩展了BaseFacet。BaseFacet是一个实现Facet接口的抽象类。 SimpleFacet,MultiValueFacet和RangeFacet是可以与任何索引字段一起重用的facets实现类。 当你对过滤单值字段感兴趣时,应该使用SimpleFacet,当你对过滤多值字段感兴趣时,应使用MultiValueFacet。 如果你对通过指定字段的值范围来过滤感兴趣时,请使用RangeFacet。 AssetEntriesFacet和ScopeFacet扩展自MultiValueFacet并对特定的索引字段进行操作。 AssetEntriesFacet在entryClassName字段上操作,ScopeFacet在groupId(或scopeGroupId)字段上操作。 ModifiedFacet扩展了RangeFacet并在一个特定的索引字段上操作:modifiedDate。

例如,假设你正在开发一个自定义搜索portlet,该portlet只应搜索特定站点中的特定类型的assets。 以下示例显示了如何配置Search Context以实现此目的:

Facet assetEntriesFacet = new AssetEntriesFacet(searchContext);
assetEntriesFacet.setStatic(true);            
searchContext.addFacet(assetEntriesFacet);

String[] entryClassNames = { oneCustomEntity.class.getName(), anotherCustomEntity.class.getName() }; // Replace this value
searchContext.setEntryClassNames(entryClassNames);

Facet scopeFacet = new ScopeFacet(searchContext);
scopeFacet.setStatic(true);            
searchContext.addFacet(scopeFacet);

long[] groupIds = { oneGroupId, anotherGroupId } // Replace this value
searchContext.setGroupIds(groupIds);

注意,AssetEntriesFacet仅对entryClassName字段进行操作,而ScopeFacet仅对groupId(或scopeGroupId字段)进行操作。另外,请Search portlet documentation中回想一下,静态方面(static facets)不会在UI中呈现(rendered)。静态facets使用预设值而不是用户动态应用的输入。以编程方式配置的用户无法配置的构面时,应将方面声明为static。由于用户无法配置静态构面,因此需要指定应搜索的asset type和group ID。为此,你需要填充entryClassNames和groupIds数组,并通过searchContext.setEntryClassNames(…)和searchContext.setGroupIds(…)方法调用将它们添加到search context中。asset type名称不属于entryClassName数组的任何索引文档都将从搜索结果中过滤掉。同样,其groupId不属于groupIds数组的任何索引文档都会从搜索结果中过滤掉。

Customized Search Filtering - 自定义搜索过滤

有时,你可能需要实现非常特定类型的搜索过滤器。 例如,假设你需要搜索文档和媒体库中的Web内容文章和PDF文件。 这种要求不适合分片实现。 由于方面是在整个结果集中计算的度量标准,因此使用方面向下钻取(drill down)(此处意思是过滤搜索结果)的能力作为过滤方式,可能会导致性能不佳以及过于复杂的方面配置。 向下钻取(drill down)意味着手动将过滤器应用于搜索。

图1:此处,用户通过手动选择Liferay站点和Document assets类型来drill down(过滤搜索结果)。

如果你需要不适合用方面实现的特定过滤器,你仍然可以使用Liferay的search API。 你可以在search context中设置布尔子句,来代替将facet添加到search context中。 也就是说,不使用searchContext.addFacet(Facet facet),而是使用searchContext.setBooleanClauses(BooleanClause[] booleanClauses)。 这种方式允许你将任意数量的筛选条件作为布尔子句数组传递给search context。 以这种方式实现的过滤比通过facet API实现的效率高几倍。 布尔子句API的另一个优点是它支持诸如排除(例如,(-field:not_this_value))之类的功能,而facet不支持这些功能。

这样的话再来实现需要搜索文档和媒体库中的Web内容文章和PDF文件的情况。 你就可以开发自定义搜索portlet来满足此用例。 以下步骤说明如何创建JSP hook以自定义Search portlet以满足此用例。

  1. 创建一个新的Liferay hook project。 使用Liferay IDE创建新的Liferay hook project,请选择File → New Liferay Plugin Project,选择Hook plugin type,然后单击Finish。

  2. 如果你正在使用Liferay IDE,请在Package Explorer中右键单击项目,然后选择New Liferay Hook Configuration 。 选中Custom JSPs框,然后单击Next。 将Custom JSP文件夹保留为/custom_jsps,然后单击Add from Liferay… 然后重写JSP文件。 选择html / portlet / search / init.jsp和html / portlet / search / main_search.jsp,然后单击Finish。
    如果你没有使用Liferay IDE,请在项目的docroot / WEB-INF文件夹中创建一个liferay-hook.xml文件,并向其中添加以下内容:

    <?xml version="1.0"?> /custom_jsps

然后在项目中的docroot文件夹下创建html/portlet/search/custom_jsps 目录,从Liferay的源码中复制portal-web/docroot/html/portlet/search/init.jsp ,portal-web/docroot/html/portlet/search/main_search.jsp html/portlet/search/main_search.jsp 这些文件到刚创建的文件夹中。

  1. 编辑docroot/custom_jsps/html/portlet/search/main_search.jsp文件找到以下行代码:
    searchContext.setStart(mainSearchSearchContainer.getStart());

在以上代码下方添加:

Query stringQuery = StringQueryFactoryUtil.create("entryClassName:com.liferay.portlet.journal.model.JournalArticle (+entryClassName:com.liferay.portlet.documentlibrary.model.DLFileEntry +extension:pdf)");

BooleanClause clause = BooleanClauseFactoryUtil.create(searchContext, stringQuery, BooleanClauseOccur.MUST.getName());

searchContext.setBooleanClauses(new BooleanClause[] {clause});

在上面构造的查询中,你指定要搜索索引文档,其中entryClassName等于JournalArticle,或者entryClassName等于DLFileEntry,extension等于pdf。 有关Lucene查询语法的更多信息,请参阅Lucene的documentation。

  1. 编辑docroot/custom_jsps/html/portlet/search/init.jsp 文件添加必须的imports。找到这行代码:
    <%@ page import=“java.util.LinkedList” %>

在这行代码下面添加以下:

<%@ page import="com.liferay.portal.kernel.search.SearchContext" %>
<%@ page import="com.liferay.portal.kernel.search.BooleanClause" %>
<%@ page import="com.liferay.portal.kernel.search.BooleanClauseFactoryUtil" %>
<%@ page import="com.liferay.portal.kernel.search.BooleanClauseOccur" %>
<%@ page import="com.liferay.portal.kernel.search.StringQueryFactoryUtil" %>
<%@ page import="com.liferay.portal.kernel.search.Query" %>

完成上述步骤后,部署hook plugin并测试Search portlet。 检查它是否仅返回带有.pdf文件扩展名的Web内容文章或文档或媒体文件作为搜索结果。 注意:如果你只希望将搜索portlet自定义应用于单个站点,请使用application adapter hook。 有关详细信息,请参阅 Application Adapters。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值