Liferay中如何按自定义扩展字段date对assetEntry条目进行排序
解决方案
你可以根据你的数据规模选择下面两种方案,均不需要额外修改Asset内置字段,也不会产生额外的频繁数据库请求:
方案1:内存排序(适合过滤后条目数<1000的场景,实现成本最低)
你现有代码中已经在过滤环节拿到了自定义日期字段date2,只需在组装结果时附加排序字段,最后直接用Freemarker内置的sort_by方法排序即可,全程在内存完成,无额外数据库开销:
<!-- 原有过滤逻辑保持不变,仅修改entries组装逻辑 --> <#if bContains == 1> <!-- 组装为带排序字段的Map,而非直接存entry --> <#assign entries = entries + [{"assetEntry": entry, "sortDate": date2?date}] /> </#if> <!-- 过滤完成后按自定义日期排序,需要倒序就加?reverse --> <#assign sortedEntries = entries?sort_by("sortDate") /> <!-- 后续遍历直接取assetEntry即可 --> <#list sortedEntries as item> <#assign entry = item.assetEntry /> <!-- 原有渲染逻辑 --> </#list>
方案2:DynamicQuery关联Expando表查询(适合数据量大的场景,性能最优)
Liferay的自定义扩展字段默认存储在ExpandoValue表中,你可以直接在动态查询时关联该表,在数据库层面完成过滤+排序,一次查询即可得到排序后的结果,不需要在内存做二次处理:
<#assign orstf = objectUtil('com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil') orderFactoryUtil = objectUtil('com.liferay.portal.kernel.dao.orm.OrderFactoryUtil') journalClassNameId = classNameLocalService.getClassNameId("com.liferay.journal.model.JournalArticle") expandoColumnLocalService = objectUtil("com.liferay.expando.kernel.service.ExpandoColumnLocalService") <!-- 获取自定义date字段的列ID,注意第二个参数要和扩展字段所属的实体类完全匹配 --> dateColumn = expandoColumnLocalService.getColumn(company.getCompanyId(), "com.liferay.journal.model.JournalArticle", "customFields", "date") qry = assetEntryLocalService.dynamicQuery() /> <!-- 原有publishDate过滤逻辑保持不变 --> <#if startDate??> <#assign V = qry.add(orstf.ge('publishDate', startDate?date("dd.MM.yyyy") )) /> </#if> <#if endDate??> <#assign V = qry.add(orstf.le('publishDate', endDate?date("dd.MM.yyyy"))) /> </#if> <!-- 关联ExpandoValue表,匹配自定义date字段 --> <#assign qry.createAlias("ExpandoValue", "expandoVal") qry.add(orstf.eq("expandoVal.classNameId", journalClassNameId)) qry.add(orstf.eq("expandoVal.classPK", assetEntry.classPK)) qry.add(orstf.eq("expandoVal.columnId", dateColumn.getColumnId())) <!-- 按自定义日期排序,倒序就用desc --> qry.addOrder(orderFactoryUtil.asc("expandoVal.data_")) /> <!-- 直接拿到排序后的结果,后续过滤分类逻辑保持不变即可 --> <#assign entriesRaw = assetEntryLocalService.dynamicQuery(qry) />
注意:如果你的扩展字段是站点级别的,需要在关联
ExpandoValue时额外增加expandoVal.tableId的匹配条件。
方案对比
- 数据量小优先选方案1,无需修改原有查询逻辑,代码改动最小
- 数据量超过1000条优先选方案2,数据库层面完成排序,内存开销极低
- 两种方案均不需要修改Asset内置字段,也无需额外的数据库写入操作,性能远高于你最初设想的同步字段方案
内容的提问来源于stack exchange,提问作者user1769634
相关产品推荐
相关产品推荐

