闲坐敲棋

有约不来过夜半,闲敲棋子落灯花

导航

第一个Lucene.Net 例子

Posted on 2012-02-29 09:57  闲坐敲棋  阅读(379)  评论(0编辑  收藏  举报

以全国目的地举例,通过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, null10000, 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 方法生成索引。