织梦arclist如何过滤重复文章
arclist
去重
SQL优化
重复文章是怎么产生的
织梦 {dede:arclist} 在多栏目调用、推荐位调用、tag 聚合时,经常会出现同一篇文章被多次列出。常见原因:
- 同一篇文章被指定到多个栏目(多栏目发布);
- 首页同时调用「最新」和「推荐」,推荐文章又是最新发布的;
- tag 聚合页和栏目列表页内容重叠;
- 采集入库时未做去重判断。
方案一:用 idlist 排除已展示的文章
第一个 arclist 调出文章后,把它们的 ID 收集起来,传给下一个 arclist 的 idlist 参数做反向排除:
<!-- 第一块:调用最新5条 -->
{dede:arclist row='5' orderby='pubdate'}
[field:id runphp='yes']
global $exclude_ids;
$exclude_ids[]=@me;
[/field:id]
<li>[field:title/]</li>
{/dede:arclist}
<!-- 第二块:调用其他,排除已显示的 -->
{dede:arclist row='5' orderby='pubdate' idlist=''}
[field:id runphp='yes']
global $exclude_ids;
if(in_array(@me, $exclude_ids)){@me='';}else{@me='显示';}
[/field:id]
{/dede:arclist}
这个写法依赖 runphp,对服务器性能有少量影响。
方案二:用 flag 互斥
把首页「头条」文章标记为 h,「推荐」标记为 c,调用时分别取,避免重复:
{dede:arclist flag='h' row='1'}...{/dede:arclist}
{dede:arclist flag='c' row='5'noflag='h'}...{/dede:arclist}
noflag='h' 表示排除带头条属性的文章。
方案三:SQL层面 DISTINCT 去重
使用 {dede:sql} 直接写 SQL,GROUP BY 文章 ID:
{dede:sql sql="SELECT DISTINCT arc.id,arc.title,arc.pubdate
FROM dede_archives arc
LEFT JOIN dede_arctype t ON arc.typeid=t.id
WHERE arc.arcrank>-1
AND (arc.typeid IN (1,2,3) OR FIND_IN_SET(arc.typeid, t.typeid))
GROUP BY arc.id
ORDER BY arc.pubdate DESC
LIMIT 10"}
<li><a href="/view.php?aid=[field:id/]">[field:title/]</a></li>
{/dede:sql}
方案四:自定义函数过滤
在 include/extend.func.php 加一个全局去重函数:
$GLOBALS['shown_ids']=array();
function FilterDuplicated($id){
if(in_array($id, $GLOBALS['shown_ids'])){
return false; // 已显示过
}
$GLOBALS['shown_ids'][]=$id;
return true;
}
模板里:
{dede:arclist row='10' orderby='pubdate'}
[field:id runphp='yes']
if(!FilterDuplicated(@me)){ @me='HIDE'; } else { @me=''; }
[/field:id]
[field:array runphp='yes']
if(@me['id']==='HIDE'){ @me=''; }else{
@me="<li><a href='{@me['arcurl']}'>{@me['title']}</a></li>";
}
[/field:array]
{/dede:arclist}
注意:runphp 方案在数据量大时性能下降明显,建议每页 arclist 数量不超过 30 条,并配合静态缓存。
方案五:从源头治理——禁止一稿多投
采集或后台发布时,统一用一个主栏目,需要联动展示通过 arclist 的 typeid='1,2,3' 多栏目调用即可,不要真把同一篇文章复制到多个栏目。这是最根本的去重方法。
查库排查重复
定期用以下 SQL 检查是否有重复标题的文章:
SELECT title, COUNT(*) AS cnt
FROM `dede_archives`
GROUP BY title
HAVING cnt > 1
ORDER BY cnt DESC;
发现后通过后台「文档维护」批量删除或合并。
行动建议
先跑一遍上面的排查 SQL,看看站点里是否真的存在重复文档;如果数量不少,先做源头治理;模板层面的去重则用 noflag 或 idlist 方案更轻量。把每个首页推荐位都规划清楚用途(头条、最新、热门、推荐),互不重叠,自然就没有重复问题了。SEO 上一稿多 URL 是大忌,趁早治理对收录质量有明显帮助。