You need to enable JavaScript to run this app. Liferay 7.1自定义搜索结果与facets 过滤无layoutId内容方案咨询
优惠活动
大模型
产品
解决方案
定价
更多

Liferay 7.1自定义搜索结果与facets 过滤无layoutId内容方案咨询

你当前在JSP Fragment中实现过滤的方式确实不符合Liferay开发规范,属于展示层后置过滤,会导致搜索分页计数错误、Facets统计不准等问题。你提到的通过Action Command Hook修改对应Java Action类的思路虽然可实现需求,但属于侵入性修改,后续版本升级兼容性风险极高,也不是最优解。

推荐实现方案

Liferay提供了原生的搜索扩展点,可以无侵入实现你的过滤需求,按优先度推荐以下两种方案:

方案1:索引字段增强+查询过滤器(性能最优,推荐)

该方案在索引阶段就把Web内容关联的布局信息存入搜索索引,查询时直接通过过滤条件筛选,性能损耗最小,不会影响分页和统计功能的准确性。
操作步骤:

  1. 实现IndexerPostProcessor接口,重写postProcessDocument方法,在Web内容(JournalArticle)索引生成时,将关联的layoutId列表写入索引文档,核心代码如下:
@Component(
    immediate = true,
    property = "indexer.class.name=com.liferay.journal.model.JournalArticle",
    service = IndexerPostProcessor.class
)
public class JournalArticleLayoutIndexerPostProcessor implements IndexerPostProcessor {
    @Reference
    private JournalContentSearchLocalService journalContentSearchLocalService;

    @Override
    public void postProcessDocument(Document document, Object object) throws Exception {
        JournalArticle article = (JournalArticle) object;
        // 仅处理最新版本的文章
        if (article.isLatestVersion()) {
            long[] layoutIds = journalContentSearchLocalService.getLayoutIds(
                article.getGroupId(), false, article.getArticleId()
            );
            // 把关联布局ID列表作为关键字段存入索引
            document.addKeyword("webcontent_related_layout_ids", layoutIds);
            // 额外存入是否存在关联布局的标识字段,方便后续过滤
            document.addKeyword("webcontent_has_related_layout", layoutIds != null && layoutIds.length > 0);
        }
    }

    // 其余接口方法默认实现即可
    @Override
    public void postProcessSearchQuery(BooleanQuery searchQuery, BooleanFilter booleanFilter, Indexer<?> indexer, SearchContext searchContext) throws Exception {}
    @Override
    public void postProcessSummary(Summary summary, Document document, Locale locale, String snippet) throws Exception {}
}
  1. 实现IndexerQueryContributor接口,在搜索查询执行前添加过滤条件,仅返回存在关联布局的Web内容:
@Component(
    immediate = true,
    service = IndexerQueryContributor.class
)
public class JournalArticleLayoutQueryContributor implements IndexerQueryContributor {
    @Override
    public void contribute(BooleanQuery booleanQuery, Indexer<?> indexer, SearchContext searchContext) throws Exception {
        // 仅对Web内容的搜索请求添加过滤条件
        if (JournalArticle.class.getName().equals(indexer.getClassName())) {
            booleanQuery.addRequiredTerm("webcontent_has_related_layout", true);
        }
    }
}
  1. 部署模块后,重新索引所有Web内容即可生效。

方案2:搜索结果后置处理器(轻量实现,无需重建索引)

如果你不想改动索引结构,可选择在搜索查询执行完成后、结果返回前端前做过滤,适合小流量场景使用,注意需要同步修正结果总计数避免分页异常。
核心实现为实现SearchResultsProcessor接口:

@Component(
    immediate = true,
    service = SearchResultsProcessor.class
)
public class JournalArticleLayoutResultProcessor implements SearchResultsProcessor {
    @Reference
    private JournalContentSearchLocalService journalContentSearchLocalService;

    @Override
    public void process(SearchContext searchContext, SearchResults searchResults) throws SearchException {
        List<Document> filteredDocuments = new ArrayList<>();
        for (Document document : searchResults.getDocuments()) {
            // 判断是否为Web内容类型的结果
            String entryClassName = document.get(Field.ENTRY_CLASS_NAME);
            if (!JournalArticle.class.getName().equals(entryClassName)) {
                filteredDocuments.add(document);
                continue;
            }
            // 校验是否有关联布局
            long groupId = GetterUtil.getLong(document.get(Field.GROUP_ID));
            String articleId = document.get("articleId");
            long[] layoutIds = journalContentSearchLocalService.getLayoutIds(groupId, false, articleId);
            if (layoutIds != null && layoutIds.length > 0) {
                filteredDocuments.add(document);
            }
        }
        // 更新过滤后的结果和总计数
        searchResults.setDocuments(filteredDocuments);
        searchResults.setTotalHits(filteredDocuments.size());
    }
}

参考截图

搜索功能截图

内容的提问来源于stack exchange,提问作者Rafael Bravo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 02:54:05