第一个Lucene.Net 例子
2012-02-29 09:57
471 查看
以全国目的地举例,通过Lucene 构建目的地搜索,按拼音,拼音首字母
1 . 以下类是关于目的索引类,包含索引生成,索引查询方法。
public class AreaIndexBiz
{
private Analyzer analyzer;//分析器
private const int MAX_MERGE_DOC = 100;//最大合并文档数
private const int MERGE_FACTOR = 100;//合并因子
private const int Merry_Max_Doc = 1000;//内存中的最大文件数
private const int DEFAULT_MAX_FIELD_LENGTH = int.MaxValue;
private FSDirectory directory;//文件索引目录
private IndexWriter iwriter;//文件索引器
public AreaIndexBiz(string destDir)
{
analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_CURRENT); //创建一个语法分析器
directory = FSDirectory.Open(new DirectoryInfo(destDir)); //把索引文件存储到磁盘目录
//创建一个IndexWriter(存放索引文件的目录,分析器,Field的最大长度)
}
/// <summary>
/// 创建索引
/// </summary>
/// <param name="docList">文档</param>
/// <param name="destDir">索引文件夹</param>
/// <param name="strError"></param>
public bool CreateIndex(List<Document> docList, out string strError)
{
bool bResult = false;
strError = string.Empty;
try
{
PerFieldAnalyzerWrapper aWrapper = new PerFieldAnalyzerWrapper(new StandardAnalyzer());
iwriter = new IndexWriter(directory, aWrapper, true, IndexWriter.MaxFieldLength.UNLIMITED);
aWrapper.AddAnalyzer("ParentStr", new WhitespaceAnalyzer());
iwriter.SetUseCompoundFile(false);//使用复合文件
iwriter.SetMaxBufferedDocs(Merry_Max_Doc);
iwriter.SetMaxFieldLength(DEFAULT_MAX_FIELD_LENGTH);
iwriter.SetMaxMergeDocs(MAX_MERGE_DOC);
iwriter.SetMergeFactor(MERGE_FACTOR);
iwriter.SetRAMBufferSizeMB(2048.0);
foreach (Document doc in docList)
{
iwriter.AddDocument(doc); //把Document存放到IndexWriter中
}
iwriter.Optimize(); //对索引进行优化
bResult = true;
}
catch (IOException e)
{
strError = e.Message.ToString();
}
finally
{
if (iwriter != null)
{
try
{
iwriter.Close(); //关闭IndexWriter时,才把内存中的数据写到文件
}
catch (IOException e)
{
strError = e.Message.ToString();
}
}
if (directory != null)
{
try
{
directory.Close(); //关闭索引存放目录
}
catch (IOException e)
{
strError = e.Message.ToString();
}
}
}
return bResult;
}
public RAreaModel SearchIndex(string keyword, int range, int status, int pageIndex, int pageSize)
{
string strError = string.Empty;
IndexSearcher isearcher = null;
RAreaModel result = new RAreaModel();
List<AreaModel> list = new List<AreaModel>();
try
{
isearcher = new IndexSearcher(directory, true);
IndexReader reader = IndexReader.Open(directory, true);
//创建解析器
BooleanQuery query = new BooleanQuery();
Query trueQuery = null;
QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_CURRENT, "AreaName", analyzer);
query.Add(parser.Parse(keyword), BooleanClause.Occur.SHOULD);
parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_CURRENT, "ParentStr", new WhitespaceAnalyzer());
query.Add(parser.Parse(string.Format("{0}", keyword.Replace(",", " "))), BooleanClause.Occur.SHOULD);
query.Add(parser.Parse(string.Format("(PinYin:{0}* PYJC:{0}*)", keyword)), BooleanClause.Occur.SHOULD);
EzFilter filter = new EzFilter();
Filter rangeFilter = null;
if (range >= 0)
{
filter.AddFilter("Range", range.ToString());
}
if (status >= 0)
{
filter.AddFilter("Status", status.ToString());
}
trueQuery = query;
if (filter.FilterCount > 0)
{
trueQuery = filter.GetFilterQuery(trueQuery);
}
TopDocs ts = isearcher.Search(trueQuery, null, 10000, Sort.RELEVANCE); //执行搜索,获取查询结果集对象
result.TotalCount = ts.totalHits; //获取命中数
var hits = ts.scoreDocs.Skip((pageIndex-1)*pageSize).Take(pageSize).ToList() ; //获取命中的文档信息对象
//var hits = ts.ScoreDocs;
for (int i = 0; i < hits.Count(); i++)
{
AreaModel model = new AreaModel();
Document hitDoc = isearcher.Doc(hits[i].doc); //根据命中的文档的内部编号获取该文档
model.AreaId = Convert.ToInt64(hitDoc.Get("AreaId"));
model.AreaName = hitDoc.Get("AreaName");
model.PinYin = hitDoc.Get("PinYin");
model.IdStr = hitDoc.Get("S_ParentStr");
list.Add(model);
}
}
catch (IOException e)
{
strError = e.Message.ToString();
}
catch (ParseException e)
{
strError = e.Message.ToString();
}
finally
{
if (isearcher != null)
{
try
{
isearcher.Close(); //关闭搜索器
}
catch (IOException e)
{
strError = e.Message.ToString();
}
}
if (directory != null)
{
try
{
directory.Close(); //关闭索引存放目录
}
catch (IOException e)
{
strError = e.Message.ToString();
}
}
}
result.List = list;
result.ReturnMsg = !string.IsNullOrEmpty(strError) ? strError : "0000";
return result;
}
}
索引生成调用: new AreaIndexBiz(tempDir).CreateIndex(docList, out msg);
索引查询调用: new AreaIndexBiz(dir).SearchIndex(keyword, range, status, pageIndex, pageSize);
其中docList 的类型 为 List<Document>
生成方法如下:
public List<Document> GetDocument(List<AreaModel> list)
{ Field field = null; Document doc = null; List<Document> docList = new List<Document>(); foreach (AreaModel item in list) { doc = new Document(); doc.Add(new Field("AreaId", item.AreaId.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED)); field = new Field("AreaName", item.AreaName.ToString(), Field.Store.YES, Field.Index.ANALYZED); field.SetBoost(5.5F); doc.Add(field); doc.Add(new Field("PinYin", item.PinYin.ToString(), Field.Store.YES, Field.Index.ANALYZED)); doc.Add(new Field("PYJC", item.PYJC.ToString(), Field.Store.NO, Field.Index.ANALYZED)); doc.Add(new Field("ParentStr", item.IdStr.ToString().TrimStart('/').TrimEnd('/').Replace("/", " "), Field.Store.YES, Field.Index.ANALYZED)); doc.Add(new Field("S_ParentStr", item.IdStr.ToString().TrimStart('/').TrimEnd('/'), Field.Store.YES, Field.Index.NOT_ANALYZED)); doc.Add(new Field("ParentId", item.ParentId.ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED)); doc.Add(new Field("Status", item.Status.ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED)); doc.Add(new Field("Type", item.Type.ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED)); doc.Add(new Field("Range", item.Range.ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED)); docList.Add(doc); } return docList; } 从数据库中拿出所有目的地,构建Document ,通过CreatIndex 方法生成索引。
1 . 以下类是关于目的索引类,包含索引生成,索引查询方法。
public class AreaIndexBiz
{
private Analyzer analyzer;//分析器
private const int MAX_MERGE_DOC = 100;//最大合并文档数
private const int MERGE_FACTOR = 100;//合并因子
private const int Merry_Max_Doc = 1000;//内存中的最大文件数
private const int DEFAULT_MAX_FIELD_LENGTH = int.MaxValue;
private FSDirectory directory;//文件索引目录
private IndexWriter iwriter;//文件索引器
public AreaIndexBiz(string destDir)
{
analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_CURRENT); //创建一个语法分析器
directory = FSDirectory.Open(new DirectoryInfo(destDir)); //把索引文件存储到磁盘目录
//创建一个IndexWriter(存放索引文件的目录,分析器,Field的最大长度)
}
/// <summary>
/// 创建索引
/// </summary>
/// <param name="docList">文档</param>
/// <param name="destDir">索引文件夹</param>
/// <param name="strError"></param>
public bool CreateIndex(List<Document> docList, out string strError)
{
bool bResult = false;
strError = string.Empty;
try
{
PerFieldAnalyzerWrapper aWrapper = new PerFieldAnalyzerWrapper(new StandardAnalyzer());
iwriter = new IndexWriter(directory, aWrapper, true, IndexWriter.MaxFieldLength.UNLIMITED);
aWrapper.AddAnalyzer("ParentStr", new WhitespaceAnalyzer());
iwriter.SetUseCompoundFile(false);//使用复合文件
iwriter.SetMaxBufferedDocs(Merry_Max_Doc);
iwriter.SetMaxFieldLength(DEFAULT_MAX_FIELD_LENGTH);
iwriter.SetMaxMergeDocs(MAX_MERGE_DOC);
iwriter.SetMergeFactor(MERGE_FACTOR);
iwriter.SetRAMBufferSizeMB(2048.0);
foreach (Document doc in docList)
{
iwriter.AddDocument(doc); //把Document存放到IndexWriter中
}
iwriter.Optimize(); //对索引进行优化
bResult = true;
}
catch (IOException e)
{
strError = e.Message.ToString();
}
finally
{
if (iwriter != null)
{
try
{
iwriter.Close(); //关闭IndexWriter时,才把内存中的数据写到文件
}
catch (IOException e)
{
strError = e.Message.ToString();
}
}
if (directory != null)
{
try
{
directory.Close(); //关闭索引存放目录
}
catch (IOException e)
{
strError = e.Message.ToString();
}
}
}
return bResult;
}
public RAreaModel SearchIndex(string keyword, int range, int status, int pageIndex, int pageSize)
{
string strError = string.Empty;
IndexSearcher isearcher = null;
RAreaModel result = new RAreaModel();
List<AreaModel> list = new List<AreaModel>();
try
{
isearcher = new IndexSearcher(directory, true);
IndexReader reader = IndexReader.Open(directory, true);
//创建解析器
BooleanQuery query = new BooleanQuery();
Query trueQuery = null;
QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_CURRENT, "AreaName", analyzer);
query.Add(parser.Parse(keyword), BooleanClause.Occur.SHOULD);
parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_CURRENT, "ParentStr", new WhitespaceAnalyzer());
query.Add(parser.Parse(string.Format("{0}", keyword.Replace(",", " "))), BooleanClause.Occur.SHOULD);
query.Add(parser.Parse(string.Format("(PinYin:{0}* PYJC:{0}*)", keyword)), BooleanClause.Occur.SHOULD);
EzFilter filter = new EzFilter();
Filter rangeFilter = null;
if (range >= 0)
{
filter.AddFilter("Range", range.ToString());
}
if (status >= 0)
{
filter.AddFilter("Status", status.ToString());
}
trueQuery = query;
if (filter.FilterCount > 0)
{
trueQuery = filter.GetFilterQuery(trueQuery);
}
TopDocs ts = isearcher.Search(trueQuery, null, 10000, Sort.RELEVANCE); //执行搜索,获取查询结果集对象
result.TotalCount = ts.totalHits; //获取命中数
var hits = ts.scoreDocs.Skip((pageIndex-1)*pageSize).Take(pageSize).ToList() ; //获取命中的文档信息对象
//var hits = ts.ScoreDocs;
for (int i = 0; i < hits.Count(); i++)
{
AreaModel model = new AreaModel();
Document hitDoc = isearcher.Doc(hits[i].doc); //根据命中的文档的内部编号获取该文档
model.AreaId = Convert.ToInt64(hitDoc.Get("AreaId"));
model.AreaName = hitDoc.Get("AreaName");
model.PinYin = hitDoc.Get("PinYin");
model.IdStr = hitDoc.Get("S_ParentStr");
list.Add(model);
}
}
catch (IOException e)
{
strError = e.Message.ToString();
}
catch (ParseException e)
{
strError = e.Message.ToString();
}
finally
{
if (isearcher != null)
{
try
{
isearcher.Close(); //关闭搜索器
}
catch (IOException e)
{
strError = e.Message.ToString();
}
}
if (directory != null)
{
try
{
directory.Close(); //关闭索引存放目录
}
catch (IOException e)
{
strError = e.Message.ToString();
}
}
}
result.List = list;
result.ReturnMsg = !string.IsNullOrEmpty(strError) ? strError : "0000";
return result;
}
}
索引生成调用: new AreaIndexBiz(tempDir).CreateIndex(docList, out msg);
索引查询调用: new AreaIndexBiz(dir).SearchIndex(keyword, range, status, pageIndex, pageSize);
其中docList 的类型 为 List<Document>
生成方法如下:
public List<Document> GetDocument(List<AreaModel> list)
{ Field field = null; Document doc = null; List<Document> docList = new List<Document>(); foreach (AreaModel item in list) { doc = new Document(); doc.Add(new Field("AreaId", item.AreaId.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED)); field = new Field("AreaName", item.AreaName.ToString(), Field.Store.YES, Field.Index.ANALYZED); field.SetBoost(5.5F); doc.Add(field); doc.Add(new Field("PinYin", item.PinYin.ToString(), Field.Store.YES, Field.Index.ANALYZED)); doc.Add(new Field("PYJC", item.PYJC.ToString(), Field.Store.NO, Field.Index.ANALYZED)); doc.Add(new Field("ParentStr", item.IdStr.ToString().TrimStart('/').TrimEnd('/').Replace("/", " "), Field.Store.YES, Field.Index.ANALYZED)); doc.Add(new Field("S_ParentStr", item.IdStr.ToString().TrimStart('/').TrimEnd('/'), Field.Store.YES, Field.Index.NOT_ANALYZED)); doc.Add(new Field("ParentId", item.ParentId.ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED)); doc.Add(new Field("Status", item.Status.ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED)); doc.Add(new Field("Type", item.Type.ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED)); doc.Add(new Field("Range", item.Range.ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED)); docList.Add(doc); } return docList; } 从数据库中拿出所有目的地,构建Document ,通过CreatIndex 方法生成索引。
相关文章推荐
- VC++.net 的第一个简单例子
- 刚看了一点Spring .NET, 从第一个例子MovieFinder说起
- 刚看了一点Spring .NET, 从第一个例子MovieFinder说起(2)
- lucene.net 3.0.3、结合盘古分词进行搜索的小例子(转)
- Asp.Net 开发 第一个例子
- 使用lucene.net2.0 搜索数据库的例子<转自csdn>
- 学习Spring.NET - 第一个例子
- lucene学习的第一个例子之创建索引
- lucene.net 3.0.3、结合盘古分词进行搜索的小例子(分页功能)
- Lucene第一个入门学习例子
- Lucene第一个例子
- asp.net通过反射技术实现Ajax(3)--第一个简单的例子
- 改造Lucene第一个例子
- 第一个lucene例子
- lucene.net 3.0.3、结合盘古分词进行搜索的小例子(分页功能)
- lucene.net helper类 【结合盘古分词进行搜索的小例子(分页功能)】
- 第一个Net+Mysql的例子,比想象的简单很多
- ASP.NET MVC 第一章 我们的第一个MVC例子
- Asp.net 和 Comet 开发入门, 第一个例子
- mxnet系列教程之1-第一个例子