首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • [向luxu001207提问]今天无聊,写了个拆词程序,代码很乱,拿出来晒晒,顺便散散分 [已结贴,结贴人:luxu001207]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • luxu001207
    • 等级:
    发表于:2008-04-09 13:38:39 楼主
    以前没写过拆词程序,今天一时兴起,随手敲的代码,拆词效果不是很理想。
    本人对T-SQL很不了解,所以写的有些零乱,没有整理成函数,也没测试在大数据量的时候的运行速度

    以下代码会在数据库中建两个表(KeywordTable,msgTable )
    所以建议新建一个空数据库,然后再到查询分析器里运行以下代码...
    SQL code
    if not object_id('KeywordTable') is null drop table KeywordTable create table dbo.KeywordTable (id int identity (1,1) not null,Primary key(id),num int not null default 0, keyword nvarchar(50) not null default '词组') --以下数据用来测试的 insert into KeywordTable(num,keyword) values(1,'北京') insert into KeywordTable(num,keyword) values(1,'上海') insert into KeywordTable(num,keyword) values(1,'杭州') insert into KeywordTable(num,keyword) values(1,'系统') insert into KeywordTable(num,keyword) values(1,'测试') insert into KeywordTable(num,keyword) values(1,'留言') insert into KeywordTable(num,keyword) values(1,'流言蜚语') insert into KeywordTable(num,keyword) values(1,'无恶不作') insert into KeywordTable(num,keyword) values(1,'地区') insert into KeywordTable(num,keyword) values(1,'平果') --以上数据用来测试的 declare @keywords nvarchar(200) set @keywords='杭州系统我家在平果网名笨笨' --查询关键字 --首先创建一个虚拟表,用来存储待匹配的关键字,这个虚拟表可以加快一定的速度 declare @tb table ( id int,keyword varchar(50) ) --检测词库中匹配的词组,并将其插入虚拟表 insert @tb select [id],keyword from [KeywordTable] where charindex(keyword,@keywords)>0 --拆词,首先创建一个虚拟表 declare @keyTable table ( keyword varchar(50) ) --先把整个查询字符串插入虚拟表中(因为整个字符串其实也是一个词) insert @keyTable select @keywords union select keyword from @tb --这里先把所有匹配的关键字都插入虚拟表里了 --然后再使用游标开始拆词 declare @thisKey nvarchar(50) --拆从词库中查询出来的关键词存储到此变量 declare @leftKey nvarchar(50) --用来存储关键字左边的字符 -- declare @rightKey nvarchar(50) --用来存储关键字右边的字符 declare cursor_insert cursor for select [id] from @tb order by len(keyword) desc --定义游标,cursor_insert为游标名 declare @i int declare @charat int --关键字的位置 open cursor_insert fetch cursor_insert into @i --将ID值赋给@i while @@fetch_status=0 --判断是否到表尾 begin --取值 set @thisKey = (select top 1 keyword from @tb where [id]=@i order by len(keyword) desc) while charindex(@thisKey,@keywords)>0 begin --关键字左边的字符写入虚拟表 set @charat = charindex(@thisKey,@keywords) set @leftKey = left(@keywords,@charat-1) if @leftKey<>'' and len(@leftKey)>1 begin insert @keyTable select @leftKey end --剔除关键字 set @keywords=STUFF(@keywords,@charat,len(@thisKey),'') --这里把剔除关键字后的剩余字符串插入虚拟表 if @keywords<>'' and len(@keywords)>1 and (select count(keyword) from @keyTable where keyword=@keywords)<1 begin insert @keyTable select @keywords end --数据插入虚拟表的操作结束了 end -- fetch cursor_insert into @i --取下一记录的ID值赋给@i end close cursor_insert deallocate cursor_insert --查询 select * from @keyTable order by len(keyword) desc -- 列出拆词后的结果 --用拆解出来的关键字去查询数据库 --以下数据用来测试 if not object_id('msgTable') is null drop table msgTable create table dbo.msgTable (id int identity (1,1) not null,Primary key(id),title nvarchar(50) not null default '测试', content ntext) insert into msgTable(title,content) values('北京/上海/杭州','北京,上海,杭州都能查询到的数据') insert into msgTable(title,content) values('北京/杭州','北京,杭州都能查询到的数据') insert into msgTable(title,content) values('杭州','只有杭州能查询到的数据') insert into msgTable(title,content) values('留言','只有留言能查询到的数据') select * from msgTable t where exists(select keyword from @keyTable where charindex(keyword,t.title)>0)
    100  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-09 13:41:461楼 得分:3
    拿出来晒晒,顺便散散分
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-09 13:45:512楼 得分:3
    greate...
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-09 13:50:223楼 得分:3
    UP
    顺便接分
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • luxu001207
    • 等级:
    发表于:2008-04-09 13:54:454楼 得分:0
    这种天气,只想睡觉...
    哎~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-09 14:22:535楼 得分:3
    这是真的,闷闷的
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-09 14:28:266楼 得分:3
    引用 4 楼 luxu001207 的回复:
    这种天气,只想睡觉...
    哎~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • possible_Y
    • 等级:
    发表于:2008-04-09 14:32:077楼 得分:3
    SQL Server不适合做逻辑运算
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • luxu001207
    • 等级:
    发表于:2008-04-09 14:41:128楼 得分:0
    引用 7 楼 possible_Y 的回复:
    SQL Server不适合做逻辑运算

    改天不困的时候俺换C#写一个...

    哎~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-09 15:03:129楼 得分:3
    为什么要怎么做呢?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-09 15:09:0310楼 得分:3
    用不到索引而且还游标,估计也没有速度可言
    不过支持原创~~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • snlixing
    • 等级:
    发表于:2008-04-09 15:12:1011楼 得分:3
    接分
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-09 15:20:1812楼 得分:3
    我要接分,我要接分``````````````````` 支持原创~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-09 15:28:1113楼 得分:3
    引用 7 楼 possible_Y 的回复:
    SQL Server不适合做逻辑运算
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-09 15:29:5514楼 得分:3
    up
    接分
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • luxu001207
    • 等级:
    发表于:2008-04-09 15:52:1115楼 得分:0
    引用 10 楼 gingerkang 的回复:
    用不到索引而且还游标,估计也没有速度可言 
    不过支持原创~~

    可以怎么做?
    发个思路出来,我改改...
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-09 16:28:0916楼 得分:3
    引用 15 楼 luxu001207 的回复:
    可以怎么做? 
    发个思路出来,我改改...


    不知道哦,分词本身是很复杂的,谈到搜索效率肯定需要用到索引
    你的分词方法需要探讨,而且词库的维护也不是一件简单的事情,你搜索的时候用charindex根本用不到索引,所以觉得有问题.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • luxu001207
    • 等级:
    发表于:2008-04-09 16:34:1017楼 得分:0
    不用charindex我就想不出用什么来检索“某个字符串出现在另一个字符串”了...
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-09 16:38:0718楼 得分:10
    查找内容需要用到全文索引,用like含左匹配,charindex,patindex都不能用到索引
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • songpengasp
    • 等级:
    发表于:2008-04-09 16:39:2919楼 得分:3
    把原理说下先
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • songpengasp
    • 等级:
    发表于:2008-04-09 16:40:3120楼 得分:3
    某个字符串出现在另一个字符串

    replace  然后判断长度  

    哈哈
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • luxu001207
    • 等级:
    发表于:2008-04-09 16:49:0521楼 得分:0
    引用 18 楼 gingerkang 的回复:
    查找内容需要用到全文索引,用like含左匹配,charindex,patindex都不能用到索引

    SQL code
    --select * from msgTable t where exists(select keyword from @keyTable where charindex(keyword,t.title)>0) --最后一句改成下面的,这回可以创建全文索引了^_^谢谢提醒,其它暂时还没修改好... select msg.*,k.keyword from msgTable as msg,@keyTable as k where msg.title like '%' + k.keyword + '%'
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • luxu001207
    • 等级:
    发表于:2008-04-09 16:50:1122楼 得分:0
    引用 20 楼 songpengasp 的回复:
    某个字符串出现在另一个字符串 

    replace  然后判断长度   

    哈哈

    那我不如用charindex ^_^
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-09 17:19:1723楼 得分:3
    jf
    学习
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-09 17:21:0124楼 得分:3
    路过,接分
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-09 17:52:4025楼 得分:3
    jf+xx
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-04-09 18:10:4126楼 得分:3
    CSDN还是散分的帖子火爆呀
    修改 删除 举报 引用 回复