前些日子写了一个搜索引擎,有关维度网的全局搜索,成功Debug,代码如下,欢迎批斗!

        /// <summary>
        
/// 建立索引
        
/// </summary>
        
/// <returns></returns>
        public void CreateIndex()
        {
            
string indexPath = Server.MapPath("index");//定义索引文件存放路径
            IndexWriter writer = new IndexWriter(indexPath, new StandardAnalyzer(), true);
            
//第一个参数是路径
            
//第二个是索引分词器,不同的分词器代表不同的存放方式,目前分词仍没有达到100%标准
            
//第三个参数是是否覆盖已存在的索引(不覆盖即以追加的形式写入文件)
            SqlDataReader myred = ExecuteQuery("select title,content from article");//数据集
            while (myred.Read())
            {
                Document doc 
= new Document();//初始化索引文档,就像一张白纸
                doc.Add(new Field("title", myred["title"].ToString(), Field.Store.YES, Field.Index.TOKENIZED));
                
//向白纸写入键值对,索引是以哈希算法(依我理解)对文件的键值对进行搜索
                
//Field.Store.YES对索引字段进行存储,也就是返回的结果有该字段,相反Field.Store.NO就是不存储
                
//Field.Index.TOKENIZED,对该字段进行分词处理,类似TSQL的like %% ,UN_TOKENIZED就是不分词,全词匹配
                writer.AddDocument(doc);//将设计好的白纸文件放进索引文件里
            }
            myred.Close();
            myred.Dispose();
            writer.Optimize();
//优化索引
            writer.Close();
        }
        
/// <summary>
        
/// 搜索
        
/// </summary>
        
/// <param name="strArr">关键字</param>
        
/// <returns></returns>
        public DataTable SearchByIndex(string[] strArr)
        {
            
string indexPath = Server.MapPath("index");//定义索引文件存放路径
            string keyword = strArr[0];//获取搜索关键字(在这里只能对title进行搜索,因为索引键只有这个字段)
            Hits myhit = null;//定义命中数据集
            IndexSearcher mysea = new IndexSearcher(indexPath);//定义索引器
            
//单一模式
            QueryParser q = new QueryParser("title"new StandardAnalyzer());
            Query query 
= q.Parse(keyword);// QueryParset把查询表达式转换成Lucene内置的查询类型
            myhit = mysea.Search(query);
            
//组合搜索(这里只演示单一模式,所以//
            BooleanQuery currentQuery = new BooleanQuery();
            
//条件1
            Term termField1 = new Term("field1", strArr[1]);//第一个参数是字段名,第二个是从客户单传过来的关键字
            Query queryField1 = new TermQuery(termField1);
            currentQuery.Add(queryField1, BooleanClause.Occur.MUST);
//BooleanClause.Occur.MUST表示and
            
//条件2
            Term termField2 = new Term("field2", strArr[2]);
            Query queryField2 
= new TermQuery(termField1);
            currentQuery.Add(queryField2, BooleanClause.Occur.MUST_NOT);
//BooleanClause.Occur.MUST_NOT表示not  
            
//条件3
            Term termField3 = new Term("field3", strArr[3]);
            Query queryField3 
= new TermQuery(termField1);
            currentQuery.Add(queryField3, BooleanClause.Occur.SHOULD);
// BooleanClause.Occur.SHOULD表示or
            
//组合模式则有myhit = mysea.Search(currentQuery)
            string result = "关于:" + keyword + "  搜索到" + myhit.Length() + "个结果<br>";
            
if (myhit != null)
            {
                DataRow myrow;
                DataTable mytab 
= new DataTable();
                mytab.TableName 
= result;//这个乱来的,表鸟他
                mytab.Columns.Add("title");
                mytab.Clear();
                
for (int i = 0; i < myhit.Length(); i++)
                {
                    Document doc 
= myhit.Doc(i);
                    myrow 
= mytab.NewRow();
                    myrow[
0= doc.Get("title").ToString();
                    mytab.Rows.Add(myrow);
                    myrow.AcceptChanges();
                }
                mysea.Close();
//搜索完记得关闭索引器哦
                return mytab;
            }
            
else
            {
                
return null;
            }
        }

为什么要使用搜索引擎而不使用like%%呢?原因有二,不过一切还得让执行计划话事!
① 搜索引擎仅仅使用了空间,不用访问数据库,减少了服务器压力,以空间换速度
② like%%会避开索引扫描,降低性能,所以不可取(注:like ’_%'可以使用索引)
不过呢!Like%%同学也是有优点的,他的准确性达到100%,不是任何搜索引擎能与之媲美的,这一点还是要表扬滴。

(强烈推荐iReaper--MSDN Webcasts视频下载工具)

posted on 2010-12-02 18:22  祯の少  阅读(1635)  评论(1编辑  收藏  举报