您的位置:首页 > 其它

第一个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 方法生成索引。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: