一个Lucene.Net的Demo

  今天突然想来看一下全文检索,于是就了解了一下Lucene.Net,然后把公司目前的产品表拿来练手,写了这么个Demo。

  先看一下Demo的代码  

    public class ProductRepository
    {
        private Logger logger = new Logger(typeof(ProductRepository));

        /// <summary>
        /// 分页获取商品数据
        /// </summary>
        /// <param name="tableNum"></param>
        /// <param name="pageIndex">从1开始</param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public List<Product> QueryList(int tableNum, int pageIndex, int pageSize)
        {
            string sql = string.Format("SELECT top {2} ProductID,ProductCode,ProductName,PreferentialPrice AS Price,ProductImage AS ImageUrl FROM Product WHERE ProductID>{1};", tableNum.ToString("000"), pageSize * Math.Max(0, pageIndex - 1), pageSize);
            return SqlHelper.QueryList<Product>(sql);
        }
    }
internal class LuceneTest
{
        public static void Show(string searchInput)
        {
            FSDirectory dir = FSDirectory.Open(StaticConstant.TestIndexPath);
            IndexSearcher searcher = new IndexSearcher(dir);//查找器

            QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, "title", new PanGuAnalyzer());//解析器
            {
                string keyword = searchInput;
                {
                    Query query = parser.Parse(keyword);
                    TopDocs docs = searcher.Search(query, null, 10000);//找到的数据

                    int i = 0;
                    foreach (ScoreDoc sd in docs.ScoreDocs)
                    {
                        if (i++ < 1000)
                        {
                            Document doc = searcher.Doc(sd.Doc);
                            Console.WriteLine("***************************************");
                            Console.Write(string.Format(" id={0}", doc.Get("id")));
                            Console.Write(string.Format(" title={0}", doc.Get("title")));
                            Console.Write(string.Format(" time={0}", doc.Get("time")));
                            Console.Write(string.Format(" price={0}", doc.Get("price")));
                            Console.WriteLine("***************************************");
                        }
                    }
                    Console.WriteLine($"一共命中了{docs.TotalHits}个");
                }
            }
        }

        /// <summary>
        /// 初始化索引
        /// </summary>
        public static void InitIndex()
        {
            List<Product> productList = GetList();

            FSDirectory directory = FSDirectory.Open(StaticConstant.TestIndexPath);//FSDirectory表示存放在文件中
            using (IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED))//索引写入器
            {
                foreach (Product product in productList)
                {
                        Document doc = new Document();//一条数据              
                        doc.Add(new Field("id", product.ProductID.ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED));//一个字段  列名  值   是否保存值  是否分词
                        doc.Add(new Field("title", product.ProductName, Field.Store.YES, Field.Index.ANALYZED));
                        doc.Add(new Field("imageurl", product.ImageUrl, Field.Store.NO, Field.Index.NOT_ANALYZED));
                        doc.Add(new Field("content", "this is lucene working,powerful tool ", Field.Store.YES, Field.Index.ANALYZED));
                        doc.Add(new NumericField("price", Field.Store.YES, true).SetDoubleValue((double)(product.Price)));
                        doc.Add(new NumericField("time", Field.Store.YES, true).SetIntValue(int.Parse(DateTime.Now.ToString("yyyyMMdd"))));
                        writer.AddDocument(doc);//写进去
                }
                writer.Optimize();//优化合并
            }
        }
        /// <summary>
        /// 数据库取5000条数据测试
        /// </summary>
        /// <returns></returns>
        private static List<Product> GetList()
        {
            ProductRepository repository = new ProductRepository();
            List<Product> productList = repository.QueryList(1, 1, 5000);
            return productList;
        }
}
class Program
{
    static void Main(string[] args)
    {
        LuceneTest.InitIndex();
        
        string input;
        while ((input = Console.ReadLine()).ToUpper() != "EXIT")
        {
            if (input == "") continue;

            LuceneTest.Show(input);
        }
    }
}

  现在来看一下LuceneTest的InitIndex方法。

  FSDirectory directory = FSDirectory.Open(StaticConstant.TestIndexPath); 该语句表示将创建的索引保存到文件中;

  IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED)  接着我们创建了一个writer,并指定存放索引的目录为刚创建的directory,使用的分析器为PanGuAnalyzer,第三个参数说明如果已经有索引文件在索引目录下,我们将覆盖它们。

  我们循环遍历productList,创建Document,然后往Document添加Filed。这里说明一下Document是表示含文档的数据结构,定义了存储文档的数据结构,Field类定义了document一个域。Field有两个属性可选:存储和索引。通过存储属性你可以控制是否对这个Field进行存储;通过索引属性你可以控制是否对该Field进行索引。最后将document加入到IndexWriter里,使用IndexWriter.Optimize()进行优化合并。

  之后我们可以看到在我们制定的目录下生成了下面的文件

  最后我们在Show方法中使用 IndexSearcher 进行检索。

原文地址:https://www.cnblogs.com/jesen1315/p/11065331.html