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();
                }
            }
        }
    }
}

 

posted on 2016-09-20 14:04  APJE  阅读(124)  评论(0)    收藏  举报