用Lucene.net对数据库建立索引及搜索
最近我一直在研究 Lucene.net ,发现Lucene.net对数据库方面建索引的文章在网上很少见,其实它是可以对数据库进行索引的,我闲着没事,写了个测试程序,竟然成功了, 可以实现对数据另类查询的一种方式(通过建索引查询),发表出来,和大家共享.
其实 Lucene.net 对数据库建索引很简单,只要把数据表里面的记录读出来,然后对每个字段索引就行了.本文中数据库的内容是某个博客表-userblog表。
1.表结构:
字段名称 字段类型 字段含义
id Varchar(11) 编号
title Varchar(50) 标题
content Text 内容
2.程序流程
1) 打开数据库;
2) 建立索引;
3) 根据索引进行全文搜索.
4.附源码:
aspx文件:
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="WebApplication4.WebForm1" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <HTML> <HEAD> <title>使用Lucene.net建立简单的数据库搜索程序</title> <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR"> <meta content="C#" name="CODE_LANGUAGE"> <meta content="JavaScript" name="vs_defaultClientScript"> <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema"> </HEAD> <body MS_POSITIONING="GridLayout"> <form id="Form1" method="post" runat="server"> <table width="100%" border="0"> <tr> <td> <asp:textbox id="tj" runat="server"></asp:textbox><asp:button id="Search" runat="server" Text="搜索"></asp:button></td> </tr> </table> <table width="100%" border="0"> <tr> <td><asp:datagrid id="SearGrid" runat="server" AutoGenerateColumns="False"> <Columns> <asp:TemplateColumn> <HeaderTemplate> 搜索结果: </HeaderTemplate> <ItemTemplate> <table width="100%" border="0"> <tr> <td>id:<%# DataBinder.Eval(Container.DataItem,"id") %> </td> </tr> <tr> <td>标题: <%# DataBinder.Eval(Container.DataItem,"title") %> </td> </tr> <tr> <td>内容: <%# DataBinder.Eval(Container.DataItem,"content") %> </td> </tr> <tr> <td> </td> </tr> </table> </ItemTemplate> </asp:TemplateColumn> </Columns> </asp:datagrid></td> </tr> </table> </form> </body> </HTML> cs代码 using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Data.SqlClient; using System.Drawing; using System.Web; using System.Web.SessionState; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using Lucene.Net; using Lucene.Net.Index; using Lucene.Net.Documents; using Lucene.Net.QueryParsers; using Lucene.Net.Search; using Lucene.Net.Analysis.Standard; using Lucene.Net.Analysis.Cn; namespace WebApplication4 { /**//// <summary> /// WebForm1 的摘要说明。 /// </summary> public class WebForm1 : System.Web.UI.Page { protected System.Web.UI.WebControls.TextBox tj; protected System.Web.UI.WebControls.Button Search; protected System.Web.UI.WebControls.DataGrid SearGrid; public string connstr="server=.;database=TopWin2;uid=sa;pwd="; private void Page_Load(object sender, System.EventArgs e) { // 在此处放置用户代码以初始化页面 if (!Page.IsPostBack) { //打开数据库表 SqlDataReader myred=OpenTable(); //建立索引 IndexWriter writer=CreateIndex(myred); } } public SqlDataReader OpenTable() { SqlConnection mycon=new SqlConnection(connstr); mycon.Open(); SqlCommand mycom=new SqlCommand("select id,title,content from userblog order by id",mycon); return mycom.ExecuteReader(); } public IndexWriter CreateIndex(SqlDataReader myred) { IndexWriter writer = new IndexWriter("c:/index/", new ChineseAnalyzer(), true); try { //建立索引字段 while(myred.Read()) { Document doc=new Document(); doc.Add(Field.Keyword("id",myred["id"].ToString())); doc.Add(Field.Text("title",myred["title"].ToString())); doc.Add(Field.Text("content",myred["content"].ToString())); writer.AddDocument(doc); } writer.Optimize(); writer.Close(); } catch(Exception e) { Response.Write(e); } return writer; } public Hits seacher(String queryString) { Hits hits=null; try { IndexSearcher mysea=new IndexSearcher("c:/index/"); Query query=QueryParser.Parse(queryString,"content",new ChineseAnalyzer()); hits=mysea.Search(query); } catch(Exception e) { Response.Write(e); } return hits; } Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码 override protected void OnInit(EventArgs e) { // // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。 // InitializeComponent(); base.OnInit(e); } /**//// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器修改 /// 此方法的内容。 /// </summary> private void InitializeComponent() { this.Search.Click += new System.EventHandler(this.Search_Click); this.Load += new System.EventHandler(this.Page_Load); } #endregion private void Search_Click(object sender, System.EventArgs e) { DataRow myrow; DataTable mytab=new DataTable(); mytab.Columns.Add("id"); mytab.Columns.Add("title"); mytab.Columns.Add("content"); mytab.Clear(); Hits myhit=seacher(this.tj.Text.Trim()); if (myhit!=null) { for(int i=0;i<myhit.Length();i++) { Document doc=myhit.Doc(i); myrow=mytab.NewRow(); myrow[0]=doc.Get("id").ToString(); myrow[1]=doc.Get("title").ToString(); myrow[2]=doc.Get("content").ToString(); mytab.Rows.Add(myrow); myrow.AcceptChanges(); } this.SearGrid.DataSource=mytab; this.SearGrid.DataBind(); } else { // } } } }
Lucene.net 是 lucene在java下移植到.net上来的。
于是 我打算做一个实验看看效果如何 以下是简单代码
1:建立索引
我一向力求最简单就实现业务需求。 于是上面的函数 8句话也就搞定了。
Lucene.Net.Analysis.Standard.StandardAnalyzer a=new Lucene.Net.Analysis.Standard.StandardAnalyzer(); IndexWriter iw=new IndexWriter(@"E:\1\index",a,true); //E:\1\index 为索引文件存放地址 string conn="数据库连接字符串"; using(DataTable dt=SqlHelper.ExecuteDataset(conn,CommandType.Text,"Select top 100 name,Intr from book ").Tables[0]) { foreach(DataRow dr in dt.Rows) { IndexBook(dr["name"].ToString(),dr["intr"].ToString(),iw); 这是关键 } } iw.Optimize(); iw.Close(); MessageBox.Show("succes"); 下面请看IndexBook 这个函数 private void IndexBook(string bookname,string bookintr,IndexWriter writer) { try { Document doc = new Document(); doc.Add(Field.Keyword("bookname", bookname)); doc.Add(Field.Text("intr", bookintr)); writer.AddDocument(doc); } catch (FileNotFoundException fnfe) { } }
索引建立完毕。现在我们开始 进行一些简单搜索
项目建立 我不多说了。打字实在麻烦。
我简单说一下 搜索返回代码
Lucene.Net.Search.IndexSearcher search=new Lucene.Net.Search.IndexSearcher(@"E:\1\index"); //把刚才建立的索引取出来 Lucene.Net.Search.Query q=Lucene.Net.QueryParsers.QueryParser.Parse("搜索关键字","intr",new Lucene.Net.Analysis.Standard.StandardAnalyzer()); Lucene.Net.Search.Hits hit =search.Search(q); lb.Items.Clear(); //lb是我测试程序中的一个 listbox for(int i=0;i<=hit.Length()-1;i++) { lb.Items.Add(hit.Doc(i).GetField("bookname").StringValue()); }
实现的效果很简单。 就是 把关键字到 intr(也就是简介)中匹配。返回相关的 bookname 最后返回一个列表。
以上是一个很简单的 搜索例子。
有兴趣的 朋友可以 尝试做一些复杂的搜索.
文章出处:DIY部落(http://www.diybl.com/course/4_webprogram/asp.net/netjs/20071226/93999.html)