搜索结果按匹配字段进行排序

 

    谈到搜索,一般就想起了SQL Server的FullTextSearch(全文搜索)功能,它确实强大,但使用起来也要做一些较为繁琐的准备工作,一般小型的项目或者对搜索要求(包括性能需求)不是很高的情况下实用它还是有点太重型了。简单的搜索用SQL查询即可,但一般面临的一个问题就是如何对搜索结果按匹配字段进行优先级排序

    例如有个产品表(Products),它的字段包:括产品ID产品名称产品类别产品品牌产品简介产品详细介绍

字段类型
ProdIDint
ProdNamenvarchar
CategoryNamenvarchar
ProdBrandnvarchar
ProdIntronvarchar
ProdDescriptionnvarchar

  现在我们要求通过某个关键字从Products表中搜索包含该关键字的记录,凡是以下任何一个字段包含该关键字的记录都列出来:ProdName, CategoryName , ProdBrand, ProdIntro, ProdDescription。 并且搜索结果按照前述字段的匹配优先级进行排序:

  1)先列出字段ProdName匹配关键字的记录,然后列出字段CategoryName匹配关键字的记录,依此类推,最后列出字段ProdDescription匹配关键字的记录;

  2)在字段ProdName匹配关键字的所有记录中,先列出字段CategoryName也匹配关键字的记录,然后列出字段ProdBrand也匹配关键字的记录,依次类推…

  3)按照规则2递归排序每个记录分组……

  搜索匹配该关键字的所有记录的SQL语句倒很简单:

SELECT * from Products WHERE ProdName like ‘%KeyWord%' or CategoryName like ‘%KeyWord%' or ProdBrand like ‘%KeyWord%' or ProdIntro like ‘%KeyWord%' or ProdDescription like ‘%KeyWord%'

  但对搜索出的结果进行匹配优先级排序稍微有点困难。在用简单的SQL进行搜索时有两种方式来达到这个排序的目的:加权法多字段排序法(我瞎取的名字^-^)。

一、加权法

 对搜索的每条记录计算出一个排序权值来,然后将所有搜索结果按照这个排序权值进行降序排列即可。每条被搜索出的记录的排序权值为该记录所有字段的权值之和。某个字段的权值取决于该字段是否匹配关键字,如果不匹配则为,如果匹配则为改字段的匹配权值。字段的匹配权值计算方式为:

   fieldPriority = 2的i次冥i为该字段在所有被搜索的字段优先级排序中倒排的位置

 例如,在我们示例中各字段的匹配权值为:

字段

倒排位置

匹配权值

ProdName

16

CategoryName

8

ProdBrand

4

ProdIntro

2

ProdDescription

1

    之所以采用这种算法,是为了确保某个字段匹配的记录的排序权值不会低于另外一条不匹配该字段后续字段都匹配的记录的排序权值。例如记录A中仅仅ProdName匹配关键字,所以它的排序权值为16,而记录B中除了字段ProdName外其他字段都匹配,则其排序权值为15(8+4+2+1=15)。但记录A仍然会排在记录B前面。

   相应的SQL大致如下:

SELECT *, (
                     (case when charIndex(ProdName,KeyWord)>-1 then 16 else 0 end) +
                     (case when charIndex(CategoryName,KeyWord)>-1 then 8 else 0 end) +
                     (case when charIndex(ProdBrand,KeyWord)>-1 then 4 else 0 end) +
                     (case when charIndex(ProdIntro,KeyWord)>-1 then 2 else 0 end) +
                     (case when charIndex(ProdDescription,KeyWord)>-1 then 1 else 0 end)
                  )  as OrderPriority

from Products
WHERE ProdName like ‘%KeyWord%' or
            CategoryName like ‘%KeyWord%' or
            ProdBrand like ‘%KeyWord%' or
            ProdIntro like ‘%KeyWord%' or
            ProdDescription like ‘%KeyWord%'
Order by OrderPriority desc

二、多字段排序法

     加权法实在是有点啰嗦,倒不如直接利用SQL可以对多个字段进行排序来实现更清晰更直接。实际上我们把每个字段是否匹配的权值分散到SQL的Order里即可,大致SQL如下:

SELECT *
from Products
WHERE ProdName like ‘%KeyWord%' or
            CategoryName like ‘%KeyWord%' or
            ProdBrand like ‘%KeyWord%' or
            ProdIntro like ‘%KeyWord%' or
            ProdDescription like ‘%KeyWord%'
Order by        (case when charIndex(ProdName,KeyWord)>-1 then 0 else 1 end),
                     (case when charIndex(CategoryName,KeyWord)>-1 then 0 else 1 end),
                     (case when charIndex(ProdBrand,KeyWord)>-1 then 0 else 1 end),
                     (case when charIndex(ProdIntro,KeyWord)>-1 then 0 else 1 end),
                     (case when charIndex(ProdDescription,KeyWord)>-1 then 0 else 1 end)

    顺便贴一段在NHibernate里采用这种思路来实现搜索的代码:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL 中可以使用 LIKE 运算符进行模糊搜索,同时可以使用 CONCAT 函数将多个字段合并成一个字符串进行搜索。如果需要根据查询匹配度对结果进行排序,可以使用以下方法: 1. 使用 CONCAT 和 LIKE 函数 可以使用 CONCAT 函数将多个字段合并成一个字符串,然后使用 LIKE 运算符进行模糊搜索,例如: SELECT * FROM table WHERE CONCAT(column1, column2, column3) LIKE '%keyword%' ORDER BY (column1 LIKE '%keyword%') + (column2 LIKE '%keyword%') + (column3 LIKE '%keyword%') DESC; 这个语句中,将 column1、column2 和 column3 合并成一个字符串进行模糊搜索。然后使用 LIKE 运算符判断每个字段是否匹配关键词,匹配则返回 1,否则返回 0。最后将三个字段匹配结果相加,作为整个匹配度值,按照匹配度值进行降序排序。 2. 使用 MATCH AGAINST 函数 MySQL 中提供了 MATCH AGAINST 函数用于全文搜索,可以对多个字段进行全文搜索,并且可以根据匹配进行排序,例如: SELECT *, MATCH(column1, column2, column3) AGAINST ('keyword') AS relevance FROM table WHERE MATCH(column1, column2, column3) AGAINST ('keyword') ORDER BY relevance DESC; 这个语句中,使用 MATCH AGAINST 函数对 column1、column2 和 column3 进行全文搜索,并且将匹配度值作为一个别名为 relevance 的字段返回。然后根据 relevance 字段进行降序排序。 以上是两种常见的 MySQL 模糊搜索并根据查询匹配排序的方法,可以根据实际需求选择使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值