| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1406 人关注过本帖, 1 人收藏
标题:[经验]渚薰的ASP畅谈(十)关键字模糊匹配查询☆☆☆☆
只看楼主 加入收藏
渚薰
Rank: 6Rank: 6
等 级:贵宾
威 望:22
帖 子:1132
专家分:0
注 册:2006-8-6
收藏(1)
 问题点数:0 回复次数:4 
[经验]渚薰的ASP畅谈(十)关键字模糊匹配查询☆☆☆☆
前段时间看过一个帖子,是关于关键字模糊匹配的问题,最近我在做一个项目,刚好也需要这个功能,所以就把这个功能给完成了。在这里把我的思路分享给大家 如果有兴趣的朋友,请认真看完我下面的陈述,由于我的能力所限,其中涉及的有些问题,我是暂时忽略掉的,也希望就一些要点大家可以一起讨论。
例子:比如有关键字“打篮球”
数据库里的有四条记录,其中某个字段的值分别为“打篮球”,“篮球”,“打球”,“球”。
1、希望通过关键字,列出这四条记录。
2、匹配关键字最多的记录列在前面(比如,值是“打篮球”的记录就必须列在“篮球”和“打球”的前面,这就是记录的价值性),同时对记录集进行分页显示。
要只做到第一条并不难,主要第二条,思考:该如何来处理价值性顺序的问题呢?
一、关键字如何分割
汉语中,有这么一个规律,对于一个复合名词或者动宾结构的短语,一般来说,其中连在一起的几个字往往就是一个完整的名词或动词。比如 “打篮球”,其中“篮球”是一个名词,“打”是动词,“球”是名词。当然,这个例子会出现“打球”也是一个完整的动宾结构的现象,但 对于站内搜索,也没必要考虑处理自然语义的问题,所以,这里采取关键字的分割只是一种简单的遍历。也就是,3个3个的取,2个2个的取,1个1个的取, 且取出来的词都是连在一起的。例如“打篮球”可以分割成“打篮球”,“打篮”,“篮球”,“打”,“篮”,“球”一共6个关键字。

之后考虑价值性的问题,很显然,如果能完全匹配“打蓝球”,那么该条记录的价值性是最高的,如果匹配了“篮球”,那么价值性要比匹配 “打篮球”的低,这样依次类推,也就是能够匹配关键字的字数越多,显然价值性就越高。当然,还有实际的情况是“打球”的价值性要比“篮子”的高,但是如果按如山方法来分割, 那么“打球”的价值性和“篮子”就变成一样的了。这个其实就是处理语义的问题,这里还是忽略掉(如果这个我也能处理好,那我就取百度了……)。

这部分处理关键字分割的代码如下:
DIM SearchKey,keyLength,key,i,j
SearchKey="打篮球"
keyLength=Len(SearchKey)

FOR i=1 TO keyLength
FOR j=keyLength-i+1 TO 1 STEP -1
key=Mid(SearchKey,i,j) '截取关键字
NEXT
NEXT
'如此,就依次获得了关键字“打篮球”,“打篮”,“篮球”,“打”,“篮”,“球”
二、记录集的排序以及分页
关键字价值性问题解决后,就要处理怎样让记录来按价值性的高低来排序,同时仍旧要处理分页。关于这点补充一些知识。
1、脱机记录集
对于刚接触asp或者未仔细学习过ADO的朋友,并不会知道脱机记录集是什么。所谓脱机记录集就是,通过断开与数据库 的连接来操作记录的集合。此记录集是保存在客户端的,即游标的操作是在客户端进行的,并不在服务器端的数据库上进行。脱机记录集的好处是减轻服务器端 处理数据的压力。
2、临时表
在使用脱机记录集的情况下,如果向该记录集中添加或修改记录,并且不马上重新连接数据库更新数据,此时的记录集就是临时表。 对临时表的更改不会影响到服务器端数据库里的数据,只有当用UpdateBatch提交后,才会全部更新。
3、操作脱机记录集和临时表的代码如下:

DIM conn,rs
SET conn=Server.CreateObject("Adodb.Connection")
conn.ConnectionString="......."
conn.CursorLocation=adUseClient '必须把Connection的CursorLocation属性设置成adUseClient(值为3)
conn.Open()

SET rs=Server.CreateObject("Adodb.RecordSet")
rs.Open strSql,conn,adOpenStatic,adLockBatchOptimistic,adCmdText '必须把RecordSet的CursorType属性设置成adOpenStatic(值为3),把LockType属性设置成adLockBatchOptimistic(值为4)
SET rs.ActiveConnection=NOTHING '最后把RecordSet的ActiveConnection对象设置成NOTHING以断开与数据库的连接
回到主题上,我们就要利用脱机记录集和临时表的特性来处理排序和分页的问题。大致思路如下:
1、依次对每个分割好关键字进行模糊查询,用"LIKE '%"&key&"%'"
2、没进行一次查询,把查询获得的记录集添加到临时表中
3、执行完所有查询后,针对临时表来进行分页处理
关于记录重复必须注意的细节:假如字段的值为“打篮球”,那么在每次查询中,这条记录都会被查询到,所以在进行每次查询时必须把之前已经查询到的记录给过滤掉, 如此可以用"NOT id IN ("&之前已经查询到的记录的id值集合&")"
三、准备工作
需要获得脱机记录集,还需要有个前提工作,就是在数据库建立一个表,该表的所有字段定义和需要查询的那个表一样,但是,不要把id设置成自动编号,设置成整形或长整形即可。
例:有如下表定义 TABLE user (name AS varchar(255),info AS text,id AS int)
建立一个空表 TABLE temp_user (name AS varchar(255),info AS text,id AS int)
其中info字段是需要进行模糊匹配查询的字段
四、完整代码
DIM conn,rs,strSql,temp_rs
DIM SearchKey,keyLength,key,i,j,ids
SET conn=Server.CreateObject("Adodb.Connection")
conn.ConnectionString="......."
conn.CursorLocation=adUseClient
conn.Open()

strSql="SELECT * FROM temp_user" '查询空表temp_user来获得临时表
SET temp_rs=Server.CreateObject("Adodb.RecordSet")
temp_rs.Open strSql,conn,adOpenStatic,adLockBatchOptimistic,adCmdText
SET temp_rs.ActiveConnection=NOTHING

SearchKey="打篮球"
keyLength=Len(SearchKey)
SET rs=Server.CreateObject("Adodb.RecordSet")

ids="0" '已经查询到的记录的id值
FOR i=1 TO keyLength
FOR j=keyLength-i+1 TO 1 STEP -1
key=Mid(SearchKey,i,j) '截取关键字

strSql="SELECT * FROM user WHERE NOT id IN ("&ids&") AND info LIKE '%"&key&"%'"
rs.Open strSql,conn,adOpenFowardOnly,adLockReadOnly,adCmdText

DO UNTIL rs.Eof
temp_rs.AddNew()
temp_rs("name")=rs("name")
temp_rs("info")=rs("info")
temp_rs("id")=rs("id") '假如temp_user的id字段仍旧是自动编号的话,这样就不允许赋值了
ids=ids+","+cstr(rs("id")) '把已经查询到的记录的id值保存到集合内
rs.MoveNext()
LOOP

rs.Close()
NEXT
NEXT

'TODO 对temp_user进行分页处理,并列出数据

SET rs=NOTHING
temp_user.Close()
SET temp_user=NOTHING
conn.Close()
SET conn=NOTHING

[此贴子已经被作者于2006-8-21 0:35:45编辑过]

搜索更多相关主题的帖子: ASP 关键 经验 模糊 畅谈 
2006-08-20 19:23
tsfy2003
Rank: 1
等 级:新手上路
帖 子:27
专家分:0
注 册:2006-7-31
收藏
得分:0 
学习学习
2006-08-20 21:41
gdk2006
Rank: 4
等 级:业余侠客
威 望:8
帖 子:928
专家分:270
注 册:2006-7-2
收藏
得分:0 
回去研究一下!!

程序员的悲哀如何找女朋友?
追女解决方案百度“让她着迷”!
2006-10-09 21:21
fgwuhen
Rank: 1
等 级:新手上路
帖 子:95
专家分:0
注 册:2006-10-5
收藏
得分:0 
conn.CursorLocation=adUseClient '必须把Connection的CursorLocation属性设置成adUseClient(值为3)
这样能将查询记录保存在本机内存中吗?

2006-10-09 21:46
渚薰
Rank: 6Rank: 6
等 级:贵宾
威 望:22
帖 子:1132
专家分:0
注 册:2006-8-6
收藏
得分:0 
嗯,保存在了本机内存中

个人ajax技术专题站: " target="_blank">http://www. 我不会闲你烦,只会闲你不够烦!
2006-10-09 22:06
快速回复:[经验]渚薰的ASP畅谈(十)关键字模糊匹配查询☆☆☆☆
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.022986 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved