目录

Lucene.net站内搜索—1、SEO优化
Lucene.net站内搜索—2、Lucene.Net简介和分词
Lucene.net站内搜索—3、最简单搜索引擎代码
Lucene.net站内搜索—4、搜索引擎第一版技术储备(简单介绍Log4Net、生产者消费者模式)
Lucene.net站内搜索—5、搜索引擎第一版实现
Lucene.net站内搜索—6、站内搜索第二版

第二版功能需求

  • 自动完成
  • 热门词汇(SEO)
  • 显示分词、执行耗时
  • 分页
  • 页面美化

我们先假设用一张表来存储用户所有的关键字搜索和次数,如下:

关键字名称

搜索次数

新四大名捕

3

新圆月弯刀

4

北京爱情故事

6

这样实现的缺点:1、无法实现搜索“最近7天的热词”2、性能差,因为update qCount=qCount+1 where Keyword=“新四大名捕”需要锁定行。

搜索记录表用Guid。自动增长(标识列)是需要依赖于“上一次的值”,所以需要排队,性能差;而Guid的生成则是独立的,不需要依赖,所以性能好。

select top 10 Keyword,count(*) from T_SearchRecords where Keyword like '新四大名捕%' group by Keyword order by Count(*) desc

1、Like不一定会全表扫描。“%a%”会,而"a%"则不会。

2、group by肯定非常消耗资源。

因为对于每次搜索都要:group by、order by、where like。所有的搜索的group by、order by都是一样的,没必要重复,所以应该吧“group by、order by”结果缓存起来。

因此进行数据的汇总结果插入:T_SearchRecordsSum(Keywords,SearchCount)表。每天汇总一次,这样会有数据不及时的情况,但是并不是实时性非常强的,因此没关系,大不了提高汇总的频率。

Keywords  SearchCount

新四大名捕  5

新圆月弯刀  3

delete from T_SearchRecordsSum;
insert into T_SearchRecordsSum(Keywords,SearchCount)
select Keyword,count(*) from T_SearchRecords group by Keyword order by Count(*) desc;

最热搜索

两张表,一张明细、一张汇总,定时把明细表的数据插入汇总表,查询的时候到汇总表查询。

由于明细表的主键不需要连续,而且用自动增长字段会排队、加锁从而降低效率,因此主键用Guid。(为啥文章用自动增长?url短、好看。)

insert into T_KeyWordsRank(Id,KeyWords,SearchTimes)
select newid(), KeyWords,Count(*) from T_SearchDetails where DateDiff(day,SearchDateTime,GetDate())<=7 group by KeyWords

Group by效率低,写SQLServer的是牛人,但不是神人

Quartz.Net

Quartz.Net是一个定时任务框架,可以实现异常灵活的定时任务,开发人员只要编写少量的代码就可以实现“每隔1小时执行”、“每天22点执行”、“每月18日的下午执行8次”等各种定时任务。

Quartz.Net中的概念:计划者(IScheduler)、工作(IJob)、触发器(Trigger)。给计划者一个工作,让他在Trigger(什么条件下做这件事)触发的条件下执行这个工作

将要定时执行的任务的代码写到实现IJob接口的Execute方法中即可,时间到来的时候Execute方法会被调用。

CrondTrigger是通过Crond表达式设置的触发器,还有 SimpleTrigger等简单的触发器。可以通过TriggerUtils的MakeDailyTrigger、MakeHourlyTrigger等方法简化调用。调用代码参考备注。

实现:用Quartz.Net完成定时搜索数据汇总。

第一个用户访问我们的WebApplication的时候,Application_Start才运行。

//0 15 10 ? * *" :Fire at 10:15am every day
CronTrigger trigger = new CronTrigger("trigger1", "group1", "job1", "group1");
trigger.CronExpressionString = “ ? * *”; //每隔一段时间执行任务
IScheduler sched;
ISchedulerFactory sf = new StdSchedulerFactory();
sched = sf.GetScheduler();
JobDetail job = new JobDetail("job1", "group1", typeof(IndexJob));//IndexJob为实现了IJob接口的类 DateTime ts = TriggerUtils.GetNextGivenSecondDate(null, );//5秒后开始第一次运行 TimeSpan interval = TimeSpan.FromHours();//每隔1小时执行一次
Trigger trigger = new SimpleTrigger("trigger1", "group1", "job1", "group1", ts, null,
SimpleTrigger.RepeatIndefinitely, interval);//每若干小时运行一次,小时间隔由appsettings中的IndexIntervalHour参数指定
sched.AddJob(job, true);
sched.ScheduleJob(trigger);
sched.Start();

要关闭任务定时则需要sched.Shutdown(true)

搜索记录

搜索建议、最新热门搜索都是基于已有的用户搜索记录。SEO的歪门邪道:刷百度搜相关词汇(SEO最终目的还是让用户找到我们的网站)。定期清除旧的历史数据,防止数据库太大

每次有用户搜索都把用户的搜索行为记录下来,供热门搜索和搜索建议用。三个字段:搜索时间、搜索词(一句话)、访问者IP地址。因为自动增长字段(标识列)有加锁的机制,所以慢,这里呢的Id也不会在逻辑中有,所以用Guid(不会加锁)

使用三层,增加插入记录的方法,在搜索的时候插入记录,IP地址:Request.UserHostAddress。

todo:为了避免groupby耗时,每小时做一次group by

自动完成

关于自动搜索功能这里我使用jquery ui 来实现,先下载AutoComplete.rar下载路径:http://files.cnblogs.com/files/jiekzou/AutoComplete.rar

当然,你也可以在google搜索“JQuery AutoComplete”,找到了JQueryUI库中的AutoComplete组件。http://jqueryui.com/demos/autocomplete/

效果图如下:

新建AutoComplete.aspx

要求服务器返回搜索建议词汇的时候将词汇以字符串数组的形式(JSon格式)返回给浏览器。

不要忘了引入jquery、jqueryui的js和css,注意顺序。

autocomplete的source属性指定自动完成数据的数据来源

生命周期的问题:在用户敲入文字的时候,Autocomplete组件向ashx页面发出ajax请求,并且将ashx返回的json格式的数组显示出来。(*)defer请求

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AutoComplete.aspx.cs" Inherits="BookShop.Web.AutoComplete" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link href="/Css/themes/ui-lightness/jquery-ui-1.8.2.custom.css" rel="stylesheet" type="text/css" />
<script src="/js/jquery-1.4.2.js" type="text/javascript"></script>
<script src="/js/jquery-ui-1.8.2.custom.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () { $("#<%=txtSearch.ClientID%>").focus(function () { if ($(this).val() == "请输入搜索内容") { $(this).css("color", "black").val("");
}
}).blur(function () {
//光标离开
if ($(this).val() == "") {
$(this).css("color", "Gray").val("请输入搜索内容"); }
}); $("#<%=txtSearch.ClientID%>").autocomplete({
source: "/ashx/AutoComplete.ashx",
minLength: 1 }); });
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="txtSearch" runat="server" Width="432px" style="color:grey">请输入搜索内容</asp:TextBox>
<asp:Button ID="btnSearch" runat="server" Text="Search" />
</div>
</form>
</body>
</html>

新建一般处理程序:AutoComplete.ashx

    public class AutoComplete : IHttpHandler
{ public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
string term = context.Request.QueryString["term"];
//BLL.BookManager bll = new BookShop.BLL.BookManager();
List<Book> bookList = new List<Book>();//bll.GetBooks(term); bookList.Add(new Book {Id=,ISBN="",PublishDate=DateTime.Now,Title="bad",UnitPrice=10.00m });
bookList.Add(new Book { Id = , ISBN = "", PublishDate = DateTime.Now, Title = "Anple", UnitPrice = 10.00m });
bookList.Add(new Book { Id = , ISBN = "", PublishDate = DateTime.Now, Title = "Acccd", UnitPrice = 10.00m });
bookList.Add(new Book { Id = , ISBN = "", PublishDate = DateTime.Now, Title = "bcccd", UnitPrice = 10.00m }); List<string> list = new List<string>();
for (int i = ; i < bookList.Count; i++)
{
if (bookList[i].Title.ToLower().LastIndexOf(term.ToLower())==)
{
list.Add(bookList[i].Title);
}
}
//序列化对象
System.Web.Script.Serialization.JavaScriptSerializer js = new System.Web.Script.Serialization.JavaScriptSerializer();
context.Response.Write (js.Serialize(list.ToArray())); } public bool IsReusable
{
get
{
return false;
}
}
}

热门词汇

在搜索框下方显示搜索次数最多的语句,语句添加超链接,用户可以点击语句的超链接快捷的开始搜索。用ObjectDataSource和Repeater控件。

在搜索框下方显示热门词汇有利于SEO,方便著名的搜索引擎收录网站的搜索结果页面,因为搜索引擎只认超链接。很多站内搜索都有热门词汇就是这么回事。

热门词汇是所有访问者每次访问页面的时候都要显示的,所以需要缓存。这个是缓存的一个很好的例子,面试的时候问到缓存的问题举这个例子就很好。

显示数据库中所有搜索次数最多的语句,好吗?不好,容易形成马太效应。只取一周之内的最热门。

在经常需要进行检索的字段上添加索引,可以提高检索速度。

<div class="rp_5equalcol"><asp:HyperLink Text='<%# Eval("KeyWord")%>' NavigateUrl='<%#EvalSearchURL(Eval("KeyWord").ToString()) %>' runat="server"></asp:HyperLink></div>
private string GetPageAbsolutePath()
{
string pageurl = this.AppRelativeVirtualPath;
return this.ResolveUrl(pageurl);
} public string EvalSearchURL(string kw)
{
string pageurl = GetPageAbsolutePath();
return string.Format("{0}?kw={1}", pageurl,HttpUtility.UrlEncode(kw));
}

搜索结果分页

开发站内搜索的分页功能。

能够SEO的无刷新分页。

这里你可以使用现有的第三方分页控件,也可以自己写一个或自己改造一个,注意使用ajax无刷新分页。

Lucene.net高级

这里我只做简单介绍,有兴趣的朋友可以自己去研究下。

(*) IndexSearcher是Searcher类的一个子类,Searcher类还有其他子类,MultiSearcher(在多个索引上搜索),ParallelMultiSearcher(在多个索引上并行搜索,速度更快),做更大的搜索引擎会用到。

(*)可以对检索过程过滤,可以实现评分大于0.8的才显示搜索结果,在搜索出的数据太多的情况下调整。搜索排序也是默认根据评分。
(*)除了PhraseQuery,还有BooleanQuery(检索包含“网络”或者“志愿者”;搜索标题或者正文中包含“搞笑电影”的资源)、FuzzyQuery(纠错匹配,用户输入“Chjna”时候也能匹配“China”,需要提供额外的纠错数据)、WildcardQuery (通配符检索,包含“搞笑*电影”)等  #mailContentContainer .txt {height:auto;}

Lucene.net站内搜索—6、站内搜索第二版的更多相关文章

  1. 联系我们_站内信息_站内资讯_网上定制衬衫|衬衫定制|衬衫定做-ChenShanLe衬衫乐

    联系我们_站内信息_站内资讯_网上定制衬衫|衬衫定制|衬衫定做-ChenShanLe衬衫乐 衬衫乐定制网是国内领先的成衣定制机构,专业从事衬衫网络在线定制.高级定制服装的价格不菲,而衬衫乐运用了&qu ...

  2. centos7内网源站建设

    centos7内网源站建设 1.部署环境: 系统:Centos7 x86_64 应用服务:nginx.createrepo.reposync 镜像源:https://mirrors.aliyun.co ...

  3. awk(流程控制、内置变量、内置函数、数组)

    摘自:http://bbs.51cto.com/thread-883948-1-1.html awk(流程控制.内置变量.内置函数.数组) ... 参考其他的资料,给大家看看.一.awk流程控制语句 ...

  4. HTML元素分类:块级元素 内联元素和内联块状元素

    在CSS中,html中的标签元素大体被分为三种不同的类型:块状元素.内联元素(又叫行内元素)和内联块状元素. 1,块状元素 常用的块状元素有: <div>.<p>.<h1 ...

  5. css块级标签,行内标签,行内块标签的转换(2)

            css块级标签,行内标签,行内块标签的转换 版权声明 本文原创作者:雨点的名字 作者博客地址:https://home.cnblogs.com/u/qdhxhz/ 在基础1中,我详细讲 ...

  6. lucene全文搜索之四:创建索引搜索器、6种文档搜索器实现以及搜索结果分析(结合IKAnalyzer分词器的搜索器)基于lucene5.5.3

    前言: 前面几章已经很详细的讲解了如何创建索引器对索引进行增删查(没有更新操作).如何管理索引目录以及如何使用分词器,上一章讲解了如何生成索引字段和创建索引文档,并把创建的索引文档保存到索引目录,到这 ...

  7. JavaScript基础:BOM的常见内置方法和内置对象

    本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. BOM的介绍 JavaScript的组成 JavaScript基础分为三 ...

  8. css 块元素、内联元素、内联块元素

    块元素.内联元素.内联块元素: 元素就是标签,布局中常用的有三种标签,块元素.内联元素.内联块元素,了解这三种元素的特性,才能熟练的进行页面布局. 块元素: 块元素,也可以称为行元素,布局中常用的标签 ...

  9. 字王·国标二级字库汉字GB内码un码三合一对照表2016版

    国标二级字库汉字GB内码un码三合一对照表 字王2016版 汉字内码表,是制作字库的基础,简单.便利的版本很少,根据实战经验,特此制作这个三合一版本的汉字.GB内码.Unicode码对照表: l 提供 ...

随机推荐

  1. 【WP开发】WebView控件应用要点

    WebView控件我就不多作详细的介绍,相信大家都懂的,就算你没用过,你看他的名字和长相都知道它的用途了.就是用来显示HTML内容的. 在WP 8.1的Runtime App中,这个控件大致有以下几个 ...

  2. 【WP 8.1开发】解决摄像头翻转问题(RuntimeApp篇)

    昨天,我非常马虎地给大家说了有关处理物理摄像头翻转的话题,今天,还是这个话题,而且内容不差,只是为了完整性,顺便也提供了运行时API的版本,其实实现起来与SL框架版本差不多,毕竟这两个框架都有不少AP ...

  3. dpi 、 dip 、分辨率、屏幕尺寸、px、density 关系以及换算

    一.基本概念 dip        : Density independent pixels ,设备无关像素. dp        :就是dip px        : 像素 dpi       :d ...

  4. 转载--linux filesystem structures

    In this article, let us review the Linux filesystem structures and understand the meaning of individ ...

  5. Spring应用教程-2 方法注入

    作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) 我们通常使用lookup方法注入,它可使Spring替换一个Bean的抽象或具体方法,返回查找容器中,其他Bea ...

  6. 使用etcd+confd管理nginx配置

    1.前言 最近在项目中用nginx做反向代理,需要动态生成nginx的配置.大概流程是用户在页面上新增域名.http或https协议以及端口信息,后台会根据域名自动生成一个nginx的server配置 ...

  7. Azure Redis Cache (1) 入门

    <Windows Azure Platform 系列文章目录> Microsoft Azure Redis Cache基于流行的开源Redis Cache. 1.功能 Redis 是一种高 ...

  8. Android数据库表的创建和数据升级操作

    之前的文章有提到,可以在xml文件中配置数据库信息:http://www.cnblogs.com/wenjiang/p/4492303.html,现在就讲如何利用这些信息类构建数据库. xml文件大概 ...

  9. PyQt写的五子棋

    技术路线 GUI的实现 使用PyQt技术作为基础.PyQt是一个支持多平台的客户端开发SDK,使用它实现的客户端可以运行在目前几乎所有主流平台之上. 使用PyQt,Qt设计器实现UI,通过pyuic4 ...

  10. Eclipse窗口总是在最前的解决办法

    Eclipse窗口总是在最前的解决办法 状况: Eclipse在偶然的情况下,会莫名其妙地保持在窗口的最前面,一直保持在最前:然后alt + tab,或者鼠标点击其他窗口.想切换/激活其他窗口时,根本 ...