![6、mvc与图书商城项目代码_第1页](http://file4.renrendoc.com/view/4683845e2cf606171cb5227ce9f59e76/4683845e2cf606171cb5227ce9f59e761.gif)
![6、mvc与图书商城项目代码_第2页](http://file4.renrendoc.com/view/4683845e2cf606171cb5227ce9f59e76/4683845e2cf606171cb5227ce9f59e762.gif)
![6、mvc与图书商城项目代码_第3页](http://file4.renrendoc.com/view/4683845e2cf606171cb5227ce9f59e76/4683845e2cf606171cb5227ce9f59e763.gif)
![6、mvc与图书商城项目代码_第4页](http://file4.renrendoc.com/view/4683845e2cf606171cb5227ce9f59e76/4683845e2cf606171cb5227ce9f59e764.gif)
![6、mvc与图书商城项目代码_第5页](http://file4.renrendoc.com/view/4683845e2cf606171cb5227ce9f59e76/4683845e2cf606171cb5227ce9f59e765.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 讲师:王承伟关于搜索(站内)有一定访问量的互联网站都有站内搜索功能,比如verycd、优酷、豆瓣、cnblogs、mop、淘宝、大众点评网等。msg like 视频教程%:模糊程度太低,无法匹配几个关键词不挨着的;造成全表扫描,效率低。为什么不用数据库全文检索?数据库全文检索很傻瓜化,和普通SQL一样。数据全文检索灵活性不强。为什么不用百度、google的站内搜索( ):受制于人,会被K;索引不及时、不全面、不精准;用户体验感差这里主要讲解最有广泛应用价值的站内搜索技术,像开发百度、google那种站外搜索相关的技术不讲。 简介 是由Java版本的Lucene(卢思银)移植过来的,所有的类、
2、方法都几乎和Lucene一模一样,因此使用时参考Lucene 即可。 只是一个全文检索开发包,不是一个成型的搜索引擎,它的功能就是:把数据扔给 ,查询数据的时候从 查询数据,可以看做是提供了全文检索功能的一个数据库。 不管文本数据怎么来的。用户可以基于 开发满足自己需求的搜索引擎。 只能对文本信息进行检索。如果不是文本信息,要转换为文本信息,比如要检索Excel文件,就要用NPOI把Excel读取成字符串,然后把字符串扔给 。 会把扔给它的文本切词保存,加快检索速度。 。因为是保存的时候分词(切词),所以搜索速度非常快!分词分词是核心的算法,搜索引擎内部保存的就是一个个的“词(Word)”。英
3、文分词很简单,按照空格分隔就可以。中文则麻烦,把“北京,Hi欢迎你们大家” 拆成“北京 Hi 欢迎 你们 大家”。“the”,“,”,“和”,“啊”,“的”等对于搜索来说无意义的词一般都属于不参与分词的无意义单词(noise word)。 中不同的分词算法就是不同的类。所有分词算法类都从Analyzer类继承,不同的分词算法有不同的优缺点。(*)内置的StandardAnalyzer是将英文按照空格、标点符号等进行分词,将中文按照单个字进行分词,一个汉字算一个词。代码见备注(*)二元分词算法,每两个汉字算一个单词,“欢迎你们大家”会分词为“欢迎 迎你 你们 们大 大家”,网上找到的一个二元分词
4、算法CJKAnalyzer。面试的时候能说出不同的分词算法的差异。基于词库的分词算法,基于一个词库进行分词,可以提高分词的成功率。有庖丁解牛、盘古分词等。效率低。盘古分词算法使用具体用法参考PanguMannual.pdf打开PanGu4LuceneWebDemoBin,将Dictionaries添加到项目根路径(改名为Dict),添加对PanGu.dll(同目录下不要有Pangu.xml,那个默认的配置文件的选项对于分词结果有很多无用信息)、PanGu.Lucene.Analyzer.dll的引用把上节代码的Analyzer用PanGuAnalyzer代替运行报错?通用技巧:把Dict目录下
5、的文件“复制到输出目录”设定为“如果较新则复制”,每次生成的时候都会自动把文件拷到binDebug 下,非常方便。(只有Web应用程序有那个选项,网站没有。)永远不要对bingdebug下的东西做直接的修改,要改“源文件”。(*)Dictionaries下几个txt文件简介词库的编辑,使用DictManage.exe,对单词编辑的时候要先查找。工作的项目中要将行业单词添加到词库中,比如餐饮搜索、租房搜索、视频搜索等。(*)项目功能点:用WordDictionary类从一个几千个行业单词的文本文件中批量导入词汇到pangu分词中 核心类简介先运行写好的索引的代码,再向下讲解各个类的作用,不用背代
6、码。(*)Directory表示索引文件( 用来保存用户扔过来的数据的地方)保存的地方,是抽象类,两个子类FSDirectory(文件中)、RAMDirectory (内存中)。使用的时候别和IO里的Directory弄混了。创建FSDirectory的方法,FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath),new NativeFSLockFactory(), path索引的文件夹路径IndexReader对索引进行读取的类,对IndexWriter进行写的类。IndexReader的静态方法bool I
7、ndexExists(Directory directory)判断目录directory是否是一个索引目录。IndexWriter的bool IsLocked(Directory directory) 判断目录是否锁定,在对目录写之前会先把目录锁定。两个IndexWriter没法同时写一个索引文件。IndexWriter在进行写操作的时候会自动加锁,close的时候会自动解锁。IndexWriter.Unlock方法手动解锁(比如还没来得及close IndexWriter 程序就崩溃了,可能造成一直被锁定)。创建索引1构造函数:IndexWriter(Directory dir, Analy
8、zer a, bool create, MaxFieldLength mfl)因为IndexWriter把输入写入索引的时候, 是把写入的文件用指定的分词器将文章分词(这样检索的时候才能查的快),然后将词放入索引文件。void AddDocument(Document doc),向索引中添加文档(Insert)。Document类代表要索引的文档(文章),最重要的方法Add(Field field),向文档中添加字段。Document是一片文档,Field是字段(属性)。Document相当于一条记录,Field相当于字段。创建索引2Field类的构造函数 Field(string name,
9、 string value, Field.Store store, Field.Index index, Field.TermVector termVector): name表示字段名; value表示字段值;store表示是否存储value值,可选值 Field.Store.YES存储, Field.Store.NO不存储, PRESS压缩存储;默认只保存分词以后的一堆词,而不保存分词之前的内容,搜索的时候无法根据分词后的东西还原原文,因此如果要显示原文(比如文章正文)则需要设置存储。 index表示如何创建索引,可选值Field.Index. NOT_ANALYZED,不创建索引,Fiel
10、d.Index. ANALYZED,创建索引;创建索引的字段才可以比较好的检索。是否碎尸万段!是否需要按照这个字段进行“全文检索”。termVector表示如何保存索引词之间的距离。“北京欢迎你们大家”,索引中是如何保存“北京”和“大家”之间“隔多少单词”。方便只检索在一定距离之内的词。为什么要把帖子的url做为一个Field,因为要在搜索展示的时候先帖子地址取出来构建超链接,所以Field.Store.YES;一般不需要对url进行检索,所以Field.Index.NOT_ANALYZED案例:对1000至1100号帖子进行索引。“只要能看懂例子和文档,稍作修改即可实现自己的需求”搜索Ind
11、exSearcher是进行搜索的类,构造函数传递一个IndexReader。IndexSearcher的void Search(Query query, Filter filter, Collector results)方法用来搜索,Query是查询条件, filter目前传递null, results是检索结果,TopScoreDocCollector.create(1000, true)方法创建一个Collector,1000表示最多结果条数,Collector就是一个结果收集器。搜索所采用的分词算法必须和索引的一致。Query有很多子类,PhraseQuery是一个子类。 PhraseQ
12、uery用来进行多个关键词的检索,调用Add方法添加关键词,query.Add(new Term(字段名, 关键词),PhraseQuery. SetSlop(int slop)用来设置关键词之间的最大距离,默认是0,设置了Slop以后哪怕文档中两个关键词之间没有紧挨着也能找到。query.Add(new Term(字段名, 关键词)query.Add(new Term(字段名2, 关键词2)类似于:where 字段名 contains 关键词 and 字段名2 contains 关键词2如何实现字段名 contains 关键词 or 字段名2 contains 关键词2, BooleanQu
13、ery:MUST/ 与运算;SHOULD / 或运算;MUST_NOT/ 非运算搜索2调用TopScoreDocCollector的GetTotalHits()方法得到搜索结果条数,调用Hits的TopDocs TopDocs(int start, int howMany)得到一个范围内的结果(分页),TopDocs的scoreDocs字段是结果ScoreDoc数组, ScoreDoc 的doc字段为 为文档分配的id(为降低内存占用,只先返回文档id),根据这个id调用searcher的Doc方法就能拿到Document了(放进去的是Document,取出来的也是Document);调用do
14、c.Get(字段名)可以得到文档指定字段的值,注意只有Store.YES的字段才能得到,因为Store.NO的没有保存全部内容,只保存了分割后的词。编写检索功能,搜索“网站 志愿者”。练习分词,用户不用空格。如果确定用盘古分词,那么用盘古的Segment类更方便。检索不出来的可能的原因:路径问题,分词是否正确、盘古分词如果指定忽略大小写,则需要统一按照小写进行搜索Todo:第一个版本应该保存body和title,搜索结果形成超链接,不显示正文。搜索引擎第一版客户要求:/能把零件拼起来!检索论坛中帖子编号在900至1000之间的帖子打开一个页面点击一个【开始索引】按钮启动索引,索引完成显示耗时。
15、(对于已经被删掉的帖子不进行索引。)索引过程中要记录日志(Log4Net)(正在索引*条,索引*条的时候出错,索引完成)。一个按钮点击开始索引。打开一个页面进行搜索,不仅用户输入“网站 志愿者”可以搜索出需要的数据,用户输入“网站志愿者”也可以搜索出。query.Add(new Term(body,str)搜索结果页面显示标题和帖子的一部分(帖子的前100个字)。点击标题可以进入帖子页面。结果页面暂时不用分页。不用美化界面易错:如果帖子不存在,WebClient会报错吗?英文搜索时要转换为小写的,因为盘古分词会默认把英文转化为小写保存。解决:高亮显示在创建索引时注意: writer.Delet
16、eDocuments(new Term(id,model.Id.ToString();高亮显示,只显示包含关键词的部分。参考盘古分词的文档。从网上、文档找来的代码不用细读每行代码,先把它拿过来运行通过再说。生产者消费者模式我们现在创建索引是把数据库中的所有的数据取出来创建索引,但是如果数据量非常大,这样的话会非常的慢,那么我们怎么办呢?我们可以在网站编辑人员添加一篇新闻时,添加这篇新闻的索引。其它的不动。但是这样还是有问题的,因为编辑人员不可能就1个人,有很多人,那么他们在添加新闻,创建索引时候就有可能出现并发的问题,也就是一个人在创建索引,刚加锁,另外一个人也来创建索引,就解锁了。这样就冲突
17、了(每个用户就是一个线程)。那么我们可以将这个操作(添加索引)交个一个单独的线程,任何人要创建索引都交给这个单独的线程来完成.这样的话就只有一个线程来操作索引库,创建索引。(这就是生产者消费者模式)生产者、消费者模式:生产者、消费者不用互相等待,用仓库做缓冲。简单原理性代码见备注队列(先入先出):Queue、ConcurrentQueue(*线程安全,多线程中用这个)细节问题如何处理文章的删除。异常处理:某次出错不应该导致while(true)结束,也就是“拔网线系统不能死”。多条件查询在标题和正文中查找PhraseQuery queryMsg = new PhraseQuery();fore
18、ach (string word in CommonHelper.SplitWords(txtKW.Text) queryMsg.Add(new Term(msg, word); queryMsg.SetSlop(100);PhraseQuery queryTitle = new PhraseQuery();foreach (string word in CommonHelper.SplitWords(txtKW.Text) queryTitle.Add(new Term(title, word); queryTitle.SetSlop(100); BooleanQuery query = n
19、ew BooleanQuery(); query.Add(queryMsg, BooleanClause.Occur.SHOULD); query.Add(queryTitle, BooleanClause.Occur.SHOULD);解决:路径可配置化连接配置信息放到Web.Config的ConnectionStrings段中,而普通的自定义配置则可以写到AppSettings段中,哪些需要配置:索引的路径,被索引的网站url,索引的时间间隔。读取string indexPath = ConfigurationManager.AppSettingsIndexPath,使用Configurat
20、ionManager添加引用System.Configuration修改Web.config会造成IIS重启,这样会立即加载新的任务使用request.MapPath或者Server.MapPath把相对于网站根路径的路径转换为绝对路径(不是转换为 ,转换为 /a.aspx)。在定时任务等不在Http线程中取HttpContext.Current得到的是null,因此在定时任务中不能用HttpContext.Current.Server.MapPath方法来转换,要用HostingEnvironment.MapPath,因此可以在其他地方也用HostingEnvironment.MapPath
21、解决:地址无法发给好友用户没法把搜索结果页面发给好友,要用Get提交,这样才能得到搜索页面地址。如果采用Get方式的话,要删掉form的runat=server,变成HTML的form、method改为get,所有控件都要用HTML控件。因为只有去掉runat=server,才会完全去掉ViewState注意input不能只指定id,而应该指定name,否则不会出现在querystring中。Id是供Javascript用的,name是供querystring/Request用的。对于type=submit的input来说,只有被点击的input的name、value才会被提交给服务器。met
22、hod改为get1、要删掉form的runat=server。(唯一去掉viewstate的方法)2、所有除了DataBound控件(比如GridView、Repeater等)都要用HTML控件。Repeater、ObjectDataSource之类控件不需要runat=server的form也可以,但是VS总是提示,去源代码视图拖放、让他生成再手动删掉。3、控件注意要给表单name属性赋值。4、在后台Page_Load代码中进行响应5、IsPostBack不再有用,只能通过判断参数是否为空来判断是否是提交的页面。点搜索按钮以后如何显示搜索关键字:在aspx.cs中定义一个GetKeyWord
23、方法,input type=text id=kw1 name=kw value=/ 高级(*) IndexSearcher是Searcher类的一个子类,Searcher类还有其他子类,MultiSearcher(在多个索引上搜索),ParallelMultiSearcher(在多个索引上并行搜索,速度更快),做更大的搜索引擎会用到。(*)可以对检索过程过滤,可以实现评分大于0.8的才显示搜索结果,在搜索出的数据太多的情况下调整。搜索排序也是默认根据评分。(*)除了PhraseQuery,还有BooleanQuery(检索包含“网络”或者“志愿者”;搜索标题或者正文中包含“搞笑电影”的资源)、
24、FuzzyQuery(纠错匹配,用户输入“Chjna”时候也能匹配“China”,需要提供额外的纠错数据)、WildcardQuery (通配符检索,包含“搞笑*电影”)等统计词汇搜索次数两张表,一张明细、一张汇总,定时把明细表的数据插入汇总表,查询的时候到汇总表查询。由于明细表的主键不需要连续,而且用自动增长字段会排队、加锁从而降低效率,因此主键用Guid。(为啥文章用自动增长?url短、好看。)insert into T_KeyWordsRank(Id,KeyWords,SearchTimes)select newid(), KeyWords,Count(*) from T_SearchD
25、etailswhere DateDiff(day,SearchDateTime,GetDate()=7group by KeyWords 是一个定时任务框架,可以实现异常灵活的定时任务,开发人员只要编写少量的代码就可以实现“每隔1小时执行”、“每天22点执行”、“每月18日的下午执行8次”等各种定时任务。 中的概念:计划者(IScheduler)、工作(IJob)、触发器(Trigger)。给计划者一个工作,让他在Trigger(什么条件下做这件事)触发的条件下执行这个工作将要定时执行的任务的代码写到实现IJob接口的Execute方法中即可,时间到来的时候Execute方法会被调用搜索记录搜索建议、最新热门搜索都是基于已有的用户搜索记录。SEO的歪门邪道:刷百度搜相关词汇(SEO最终目的还是让用户找到我们的网站)。定期清除旧的历史数据,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- Cefotaxime-d3-Cefotaxim-d-sub-3-sub-生命科学试剂-MCE-1932
- 二零二五年度生物基因编辑技术研发合作保密协议
- 2025年度药店全职员工聘用合同
- 2025年度银企合作风险控制与业务拓展合同标准
- 2025年度二零二五年度门面房使用权拍卖合同
- 2025年度鱼塘承包合同书:鱼塘承包与渔业市场拓展合作合同
- 2025年度超市租赁合同排他性节假日营销活动策划协议
- 二零二五年度终止合伙合同-海洋资源开发合作终止协议
- 个人机械租赁合同范本
- 上海市电子产品购销合同
- 2024年临沂市高三一模(学业水平等级考试模拟试题)物理试卷
- 高中物理选择性必修2教材习题答案
- 我国糖尿病视网膜病变临床诊疗指南2022解读
- 锂离子电池健康评估及剩余使用寿命预测方法研究
- c30混凝土路面施工方案
- 颈椎骨折的护理常规课件
- 2022-2023学年上海市杨浦区上海同济大附属存志学校七年级数学第二学期期中综合测试模拟试题含解析
- 稿件修改说明(模板)
- GB/T 33107-2016工业用碳酸二甲酯
- GB/T 16604-2017涤纶工业长丝
- 劳动合同法经典讲义
评论
0/150
提交评论