iChos 10 采用 Lecene.Net简单实现一个站内搜索引擎
search.cs
using System.Collections.Generic;
using Lucene.Net.Analysis;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.QueryParsers;
using Lucene.Net.Documents;
using Lucene.Net.Search;
using Lucene.Net.Index;
using Lucene.Net.Store;
using Lucene.Net.Util;
namespace apje.frameWork
{
public class luceneSearch
{
public int pageCount = 0;
public int recordCount = 0;
public int pageSize = 0;
public int pageNum = 0;
//读取搜索结果
public List<dataField> getDataList(string modelMark, string searchKeyword, int sortBy, int days, int pageNum, int pageSize, int cachePage)
{
List<dataField> list = new List<dataField>();
Directory directory = FSDirectory.Open(new System.IO.DirectoryInfo(common.getMapPath("/searchIndex/") + modelMark));
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_29);
IndexSearcher indexSearcher = new IndexSearcher(directory, true);
QueryParser queryParser = new QueryParser(Version.LUCENE_29, "title", analyzer); //*************检索标题***********
Query query = queryParser.Parse(searchKeyword);
// QueryParser queryParser2 = new QueryParser(Version.LUCENE_29, "content", analyzer); //********检索正文内容**************
// Query query2 = queryParser2.Parse(searchKeyword);
BooleanQuery booleanQuery = new BooleanQuery();
booleanQuery.Add(query, BooleanClause.Occur.SHOULD);
//booleanQuery.Add(query2, BooleanClause.Occur.SHOULD);
System.DateTime now = System.DateTime.Now;
SortField sort;
if (sortBy == 1)
{
sort = new SortField("id", 4, true); //设置排序字段
}
else
{
sort = new SortField("id", 4, false); //设置排序字段
}
Sort sort2 = new Sort();
sort2.SetSort(sort);
TopFieldDocs topFieldDocs;
if (days > 0)
{
System.DateTime date = System.DateTime.Now.AddDays((double)(-(double)days));
TermRangeFilter filter = new TermRangeFilter("time", DateTools.DateToString(date, DateTools.Resolution.MILLISECOND), DateTools.DateToString(now, DateTools.Resolution.MILLISECOND), true, true);
topFieldDocs = indexSearcher.Search(booleanQuery, null, cachePage * pageSize, sort2);
}
else if (days < 0)
{
System.DateTime date = System.DateTime.Now.AddDays((double)days);
TermRangeFilter filter = new TermRangeFilter("time", DateTools.DateToString(System.DateTime.MinValue, DateTools.Resolution.MILLISECOND), DateTools.DateToString(date, DateTools.Resolution.MILLISECOND), true, true);
topFieldDocs = indexSearcher.Search(booleanQuery, null, cachePage * pageSize, sort2);
}
else
{
topFieldDocs = indexSearcher.Search(booleanQuery, null, cachePage * pageSize, sort2);
}
ScoreDoc[] scoreDocs = topFieldDocs.scoreDocs;
this.recordCount = scoreDocs.Length;
if (this.recordCount > 0)
{
if ((this.recordCount % pageSize) == 0)
{
this.pageCount = this.recordCount / pageSize;
}
else
{
this.pageCount = ((int)this.recordCount / pageSize) + 1;
}
if (pageNum < 1)
{
pageNum = 1;
}
if (pageNum > pageCount)
{
pageNum = pageCount;
}
int startNum = (pageNum - 1) * pageSize;
int endNum = startNum + pageSize;
if (endNum > this.recordCount)
{
endNum = this.recordCount;
}
this.pageNum = pageNum;
this.pageSize = pageSize;
dataField df = null;
string[] searchKeywordAry = searchKeyword.Split(' ');
for (int i = 0; i < endNum; i++)
{
df = new dataField();
Document document = indexSearcher.Doc(scoreDocs[i].doc);
string title = document.Get("title");
//string description = document.Get("description");
//for (int j = 0; j < searchKeywordAry.Length; j++) //******************关键字设置高亮********************
//{
//title = title.Replace(searchKeywordAry[j], "<span style='color:red;'>" + searchKeywordAry[j] + "</span>");
//description = description.Replace(searchKeywordAry[j], "<span style='color:red;'>" + searchKeywordAry[j] + "</span>");
//}
df.setFieldValue("id", document.Get("id"));
df.setFieldValue("title", title);
// df.setFieldValue("description", description);
df.setFieldValue("time", DateTools.StringToDate(document.Get("time")));
df.setFieldValue("cid", document.Get("cid"));
df.setFieldValue("url", document.Get("url"));
list.Add(df);
}
}
indexSearcher.Close();
directory.Close();
return list;
}
}
}
index.cs
using Lucene.Net.Analysis;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.QueryParsers;
using Lucene.Net.Documents;
using Lucene.Net.Search;
using Lucene.Net.Index;
using Lucene.Net.Store;
using Lucene.Net.Util;
using System.Collections.Generic;
namespace apje.frameWork
{
public class luceneIndex
{
public static luceneIndex instance = null;
static luceneIndex()
{
luceneIndex.instance = new luceneIndex();
}
private int mergeFactor = 10;
private int maxBufferedDoc = 500;
private int maxFieldLength = 1000;
//*****重置索引*******************
public void reset(string modelMark)
{
Directory directory = null;
IndexWriter writer = null;
try
{
//=========================设置
directory = FSDirectory.Open(new System.IO.DirectoryInfo(common.getMapPath("/searchIndex/") + modelMark));
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_29);
writer = new IndexWriter(directory, analyzer, true, new IndexWriter.MaxFieldLength(this.maxFieldLength)); //使用覆盖模式
writer.SetMergeFactor(this.mergeFactor);
writer.SetMaxBufferedDocs(this.maxBufferedDoc);
writer.SetMaxFieldLength(this.maxFieldLength);
writer.Optimize();
}
catch{
common.pageWrite("哎,重置" + cms.getModelName(modelMark) + "搜索索引时出错了");
}
finally
{
if (writer != null)
{
writer.Close();
}
if (directory != null)
{
directory.Close();
}
}
}
//*********优化索引*******************
public void optimize(string modelMark)
{
Directory directory = null;
IndexWriter writer = null;
try
{
directory = FSDirectory.Open(new System.IO.DirectoryInfo(common.getMapPath("/searchIndex/") + modelMark));
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_29);
writer = new IndexWriter(directory, analyzer, false, new IndexWriter.MaxFieldLength(this.maxFieldLength));
writer.SetMergeFactor(this.mergeFactor);
writer.SetMaxBufferedDocs(this.maxBufferedDoc);
writer.SetMaxFieldLength(this.maxFieldLength);
writer.SetUseCompoundFile(true);
writer.Optimize();
}
catch{
common.pageWrite("哎,优化" + cms.getModelName(modelMark) + "搜索索引时出错了");
}
finally
{
if (writer != null)
{
writer.Close();
}
if (directory != null)
{
directory.Close();
}
}
}
//**********重建索引**************
public void createAll(string modelMark)
{
this.reset(modelMark);
Directory directory = null;
IndexWriter writer = null;
dataField tDf = null;
List<dataField> list = db.instance.getDataList("select id from #_" + modelMark + " where status = 99");
try
{
directory = FSDirectory.Open(new System.IO.DirectoryInfo(common.getMapPath("/searchIndex/") + modelMark));
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_29);
writer = new IndexWriter(directory, analyzer, false, new IndexWriter.MaxFieldLength(this.maxFieldLength));
writer.SetMergeFactor(this.mergeFactor);
writer.SetMaxBufferedDocs(this.maxBufferedDoc);
writer.SetMaxFieldLength(this.maxFieldLength);
foreach (dataField df in list)
{
int id = df.getInt("id");
tDf = db.instance.getDataFields("select id,title,time,cid from #_" + modelMark + " where id = " + id);
if (df != null)
{
this.write(writer, df, id);
}
}
writer.Optimize();
}
catch{
common.pageWrite("哎,重建" + cms.getModelName(modelMark) + "搜索索引时出错了");
}
finally
{
if (writer != null)
{
writer.Close();
}
if (directory != null)
{
directory.Close();
}
}
}
//**********写入单条索引*******
public void write(IndexWriter writer, dataField df, int id)
{
if (df != null)
{
Document doc = new Document();
System.DateTime dt = df.getDateTime("time");
doc.Add(new Field("id", id.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
doc.Add(new Field("title", df.getString("title"), Field.Store.YES, Field.Index.ANALYZED));
doc.Add(new Field("cid", df.getString("cid"), Field.Store.YES, Field.Index.NOT_ANALYZED));
doc.Add(new Field("url", df.getString("url"), Field.Store.YES, Field.Index.NOT_ANALYZED));
//doc.Add(new Field("description", df.getString("description"), Field.Store.YES, Field.Index.NOT_ANALYZED));
//doc.Add(new Field("content", df.getString("content"), Field.Store.NO, Field.Index.ANALYZED));
doc.Add(new Field("time", DateTools.DateToString(dt, DateTools.Resolution.MILLISECOND), Field.Store.YES, Field.Index.NOT_ANALYZED));
writer.AddDocument(doc);
}
}
//**********写入单条索引*******
public void write(IndexWriter writer, int id, string title, System.DateTime time, int cid, string url)
{
Document doc = new Document();
doc.Add(new Field("id", id.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
doc.Add(new Field("title", title, Field.Store.YES, Field.Index.ANALYZED));
doc.Add(new Field("cid", cid.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
doc.Add(new Field("url", url, Field.Store.YES, Field.Index.NOT_ANALYZED));
//doc.Add(new Field("description", df.getString("description"), Field.Store.YES, Field.Index.NOT_ANALYZED));
//doc.Add(new Field("content", df.getString("content"), Field.Store.NO, Field.Index.ANALYZED));
doc.Add(new Field("time", DateTools.DateToString(time, DateTools.Resolution.MILLISECOND), Field.Store.YES, Field.Index.NOT_ANALYZED));
writer.AddDocument(doc);
}
//*******添加单条索引**************
public void add(int id, string modelMark)
{
dataField df = db.instance.getDataFields("select id,title,time,cid,url from #_" + modelMark + " where id = " + id);
if (df != null)
{
Directory directory = null;
IndexWriter writer = null;
try
{
directory = FSDirectory.Open(new System.IO.DirectoryInfo(common.getMapPath("/searchIndex/") + modelMark));
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_29);
if (!fso.isFileExists("/searchIndex/" + modelMark + "/segments.gen"))
{
this.reset(modelMark);
}
writer = new IndexWriter(directory, analyzer, false, new IndexWriter.MaxFieldLength(this.maxFieldLength)); //使用追加写索引模式
this.write(writer, df, id);
writer.Close();
directory.Close();
}
catch{
common.pageWrite("哎,写入" + cms.getModelName(modelMark) + "搜索索引时出错了");
}
finally
{
if (writer != null)
{
writer.Close();
}
if (directory != null)
{
directory.Close();
}
}
}
}
//*******添加单条索引**************
public void add(string modelMark, int id, string title, int cid, System.DateTime time, string url)
{
Directory directory = null;
IndexWriter writer = null;
try
{
directory = FSDirectory.Open(new System.IO.DirectoryInfo(common.getMapPath("/searchIndex/") + modelMark));
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_29);
// bool isExist = IndexReader.IndexExists(directory); //是否存在索引库文件夹以及索引库特征文件
writer = new IndexWriter(directory, analyzer, false, new IndexWriter.MaxFieldLength(this.maxFieldLength));
this.write(writer, id, title, time, cid, url);
}
catch
{
common.pageWrite("哎,写入" + cms.getModelName(modelMark) + "单条搜索索引时出错了");
}
finally
{
if (writer != null)
{
writer.Close();
}
if (directory != null)
{
directory.Close();
}
}
}
//************删除单条索引****************
public void delete(int id, string modelMark)
{
Directory directory = null;
IndexReader reader = null;
try
{
directory = FSDirectory.Open(new System.IO.DirectoryInfo(common.getMapPath("/searchIndex/") + modelMark));
reader = IndexReader.Open(directory, false);
Term t = new Term("id", id.ToString());
reader.DeleteDocuments(t);
reader.Close();
directory.Close();
}
catch{
common.pageWrite("哎,删除" + cms.getModelName(modelMark) + "单条搜索索引时出错了");
}
finally
{
if (reader != null)
{
reader.Close();
}
if (directory != null)
{
directory.Close();
}
}
}
}
}
浙公网安备 33010602011771号