这个需求通常指的是,根据某些预设的规则(比如文章的点击量、发布时间、关键词权重等)对搜索结果进行排序,让更“重要”或“更相关”的文章排在前面,在织梦的搜索体系中,这个“指数”主要通过修改搜索模板文件和使用自定义SQL查询来实现。
下面我将分步讲解,从简单到复杂,提供几种实现方案。
使用织梦默认的排序功能(最简单)
织梦默认的搜索结果页就提供了基础的排序功能,这可以看作是最原始的“指数”判断。
实现方法:
- 打开你的搜索结果页模板文件,路径通常是:
/templets/default/search.htm(或者你自定义的模板目录下的search.htm)。 - 在你需要显示排序按钮的地方,添加以下代码:
<div class="sort">
<span>排序:</span>
<a href="{dede:global name='phpurl'/}/search.php?kw={dede:global name='keyword'/}&searchtype=title" {dede:var.name='searchtype' value='title'}class="current"{/dede:var}>标题</a>
<a href="{dede:global name='phpurl'/}/search.php?kw={dede:global name='keyword'/}&orderby=pubdate" {dede:var.name='orderby' value='pubdate'}class="current"{/dede:var}>发布时间</a>
<a href="{dede:global name='phpurl'/}/search.php?kw={dede:global name='keyword'/}&orderby=hot" {dede:var.name='orderby' value='hot'}class="current"{/dede:var}>点击量</a>
<a href="{dede:global name='phpurl'/}/search.php?kw={dede:global name='keyword'/}&orderby=rank" {dede:var.name='orderby' value='rank'}class="current"{/dede:var}>权重</a>
</div>
代码解释:
search.php?kw={dede:global name='keyword'/}: 这是搜索的基础链接,{dede:global name='keyword'/}会自动获取用户输入的关键词。&searchtype=title: 按标题搜索。&orderby=pubdate: 按发布时间倒序排列(最新的在前)。&orderby=hot: 按点击量(click)倒序排列(点击量最高的在前)。&orderby=rank: 按文章权重(rank字段)倒序排列(权重越高的在前)。{dede:var.name='orderby' value='hot'}class="current"{/dede:var}: 这是一个判断,如果当前的排序方式是hot,就给这个链接添加class="current"样式,方便用户知道当前是按什么排序的。
优点:
- 无需修改核心文件,纯模板实现。
- 操作简单,快速。
缺点:
- 排序规则单一,无法组合多个条件(优先显示高点击量且近期的文章”)。
- 自由度低,无法自定义“指数”计算公式。
修改搜索PHP文件,实现自定义排序(推荐)
这是最常用且功能最强大的方法,我们可以修改 search.php 文件,让它支持我们自定义的排序参数,并在SQL查询中应用这个参数。
实现步骤:
第1步:修改 search.php 文件
- 打开
/plus/search.php文件。 - 找到获取
orderby参数的代码,通常在if($orderby=="")附近。 - 修改或添加
case分支,来支持我们自定义的排序方式。
示例代码:
在 search.php 中找到类似这样的代码块:
// ... 其他代码 ...
$orderby = isset($orderby) ? trim($orderby) : 'new';
if($orderby=='hot' || $orderby=='click') {
$orderby = 'click';
} else if($orderby=='pubdate' || $orderby=='senddate') {
$orderby = 'pubdate';
} else if($orderby=='lastpost') {
$orderby = 'lastpost';
} else {
$orderby = 'id';
}
// ... 其他代码 ...
修改为:
// ... 其他代码 ...
// 获取并处理排序参数
$orderby = isset($orderby) && in_array($orderby, array('hot', 'click', 'pubdate', 'rank', 'comnum', 'new')) ? trim($orderby) : 'new'; // 增加安全性判断
switch($orderby) {
case 'hot': // 按点击量排序
case 'click':
$orderby = 'click';
break;
case 'comnum': // 按评论数排序
$orderby = 'comments';
break;
case 'rank': // 按权重排序
$orderby = 'rank';
break;
case 'new': // 默认按发布时间排序
case 'pubdate':
default:
$orderby = 'pubdate';
break;
}
// ... 其他代码 ...
关键点:
- 我们增加了对
comnum(评论数)的支持。 - 默认排序改为
new(按发布时间),这在搜索场景下更合理。 - 增加了
in_array判断,防止SQL注入,提高安全性。
第2步:在搜索模板中添加自定义排序按钮
回到你的 search.htm 模板文件,在方案一的代码基础上进行修改。
<div class="sort">
<span>综合排序:</span>
<!-- 默认排序(按发布时间) -->
<a href="{dede:global name='phpurl'/}/search.php?kw={dede:global name='keyword'/}&orderby=new" {dede:var.name='orderby' value='new'}class="current"{/dede:var}>最新发布</a>
<!-- 按点击量排序 -->
<a href="{dede:global name='phpurl'/}/search.php?kw={dede:global name='keyword'/}&orderby=hot" {dede:var.name='orderby' value='hot'}class="current"{/dede:var}>最多点击</a>
<!-- 按评论数排序 -->
<a href="{dede:global name='phpurl'/}/search.php?kw={dede:global name='keyword'/}&orderby=comnum" {dede:var.name='orderby' value='comnum'}class="current"{/dede:var}>最多评论</a>
<!-- 按权重排序 -->
<a href="{dede:global name='phpurl'/}/search.php?kw={dede:global name='keyword'/}&orderby=rank" {dede:var.name='orderby' value='rank'}class="current"{/dede:var}>优先权重</a>
</div>
优点:
- 功能强大,可以自由定义多种排序方式。
- 安全性高,通过代码判断防止了恶意参数。
- 灵活性好,可以轻松添加新的排序维度(如收藏数、下载数等,前提是你的数据表里有这些字段)。
缺点:
- 需要修改PHP核心文件,升级织梦时可能需要重新修改。
实现“综合指数”排序(高级)
这是最符合“判断指数”字面意思的方案,我们设计一个公式,将多个因素(如点击量、权重、时间等)结合起来计算一个“综合分”,然后按这个分数排序。
实现思路:
- 在
search.php中,不使用简单的ORDER BY,而是构建一个更复杂的SQL查询,在ORDER BY子句中使用一个计算表达式。 - 这个表达式就是我们的“指数公式”。
示例指数公式:
综合分 = (点击量 * 0.3) + (权重 * 10) + (评论数 * 5) - (发布天数 * 0.1)
- 这个公式的含义是:点击量占30%的权重,权重占10%的权重(乘以10是为了平衡数值大小),评论数占5%的权重,发布时间越久(天数越多)扣分,以保证新内容有机会。
实现步骤:
第1步:修改 search.php 文件
- 打开
/plus/search.php。 - 找到生成最终SQL查询
$query的地方。 - 修改
ORDER BY部分,使用我们的自定义公式。
关键代码修改:
假设你已经通过方案二修改了 search.php,现在我们要在此基础上更进一步,找到类似 $query = "SELECT ... FROM ... WHERE ... ORDER BY $orderby DESC"; 的代码。
将其修改为:
// ... 获取 $keyword, $typeid 等参数的代码 ...
// --- 开始自定义排序逻辑 ---
$orderby = isset($orderby) ? trim($orderby) : 'hot'; // 默认按综合指数排序
// 获取当前时间,用于计算发布天数
$now_time = time();
$now_date = GetMkTime(MyDate('Y-m-d', $now_time));
switch($orderby) {
case 'hot':
// 按点击量排序
$addquery = " ORDER BY arc.click DESC";
break;
case 'comnum':
// 按评论数排序
$addquery = " ORDER BY arc.comments DESC";
break;
case 'rank':
// 按权重排序
$addquery = " ORDER BY arc.rank DESC";
break;
case 'new':
default:
// 默认:按综合指数排序
// 这是一个示例公式,你可以根据需要调整系数
// arc.click: 点击量, arc.rank: 权重, arc.id: 评论数(用id代替,实际可用comments), arc.senddate: 发布时间戳
$addquery = " ORDER BY (arc.click * 0.3 + arc.rank * 10 + arc.id * 0.5 - ($now_date - arc.senddate) * 0.1) DESC";
break;
}
// ... 构建主查询的代码 ...
// $query = "SELECT arc.*,tp.typedir,tp.typename,tp.corank,tp.isdefault,tp.defaultname,tp.namerule,tp.namerule2,tp.ispart,tp.moresite,tp.siteurl,tp.sitepath FROM `dede_archives` arc LEFT JOIN `dede_arctype` tp ON arc.typeid=tp.id WHERE ({$orlike}) $addquery";
// 注意:上面的 $orlike 是织梦原有的条件拼接,你需要保留它。
// 关键在于将你原有的 ORDER BY 子句替换成我们上面定义的 $addquery。
// ... 后续代码 ...
代码解释:
- 我们为
default情况(即不传orderby或传new)设置了一个复杂的ORDER BY表达式。 ($now_date - arc.senddate)计算文章发布距离现在的天数,senddate是Unix时间戳。arc.id在这里被临时用作评论数的替代,如果你的表里有comments字段,请直接使用arc.comments。- 你可以自由调整公式中的系数(如
3,10,5,1)来改变各个因素的权重。
第2步:更新模板
模板部分和方案二完全一样,因为你已经在PHP中处理了排序逻辑。
优点:
- 真正实现了“指数”判断,结果排序更智能、更符合业务需求。
- 可以非常灵活地组合各种因素,打造最理想的搜索结果排序。
缺点:
- 实现复杂,需要懂SQL和PHP。
- 公式设计需要反复测试和调整,才能达到最佳效果。
- 性能开销比简单排序稍大,但对于中小型网站影响不大。
总结与建议
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 默认排序 | 简单、快速、无修改 | 功能单一,自由度低 | 临时使用,或对排序要求不高的网站。 |
| 自定义排序 | 功能强大、灵活、安全 | 需修改PHP文件,升级需维护 | 强烈推荐,绝大多数网站都适用,能满足绝大多数排序需求。 |
| 综合指数 | 结果最智能、最灵活 | 实现复杂,需设计和调试公式 | 对搜索结果质量要求极高的商业网站、电商平台。 |
给你的建议:
- 从方案二开始:这是性价比最高的方案,能满足90%以上的需求。
- 如果方案二仍不能满足:再考虑方案三,方案三是一个进阶玩法,需要你投入更多精力去设计和测试你的“指数公式”。
希望这个详细的解析能帮助你成功实现织梦搜索页的“判断指数”功能!
