zoukankan      html  css  js  c++  java
  • Lucene.Net 与 盘古分词

    1.关键的一点,Lucene.Net要使用3.0下面的版本号,否则与盘古分词接口不一致。
    关键代码例如以下

    using System;
    using System.IO;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Lucene.Net.Analysis;
    using Lucene.Net.Documents;
    using Lucene.Net.Index;
    using Lucene.Net.Search;
    using Lucene.Net.Store;
    using Lucene.Net.Analysis.PanGu;
    using Maticsoft.DBUtility;
    using System.Data;
    using System.Diagnostics;
    namespace SearchSentence
    {
        class Program
        {
    
            public static string[] SplitWords(string content)
            {
                List<string> strList = new List<string>();
                Analyzer analyzer = new PanGuAnalyzer();//指定使用盘古 PanGuAnalyzer 分词算法
                TokenStream tokenStream = analyzer.TokenStream("", new StringReader(content));
                Lucene.Net.Analysis.Token token = null;
                while ((token = tokenStream.Next()) != null)
                { //Next继续分词 直至返回null
                    strList.Add(token.TermText()); //得到分词后结果
                }
                return strList.ToArray();
            }
    
    
            public static void CreateIndex(string strDirectory)
            {
    
                FSDirectory directory = FSDirectory.Open(new DirectoryInfo(strDirectory), new NativeFSLockFactory());
                //IndexReader:对索引库进行读取的类
                bool isExist = IndexReader.IndexExists(directory); //是否存在索引库文件夹以及索引库特征文件
                if (isExist)
                {
                    //假设索引文件夹被锁定(比方索引过程中程序异常退出或还有一进程在操作索引库)。则解锁
                    //Q:存在问题 假设一个用户正在对索引库写操作 此时是上锁的 而还有一个用户过来操作时 将锁解开了 于是产生冲突 --解决方法兴许
                    if (IndexWriter.IsLocked(directory))
                    {
                        IndexWriter.Unlock(directory);
                    }
                }
    
    
    
    
                //创建向索引库写操作对象  IndexWriter(索引文件夹,指定使用盘古分词进行切词,最大写入长度限制)
                //补充:使用IndexWriter打开directory时会自己主动对索引库文件上锁
                IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isExist, IndexWriter.MaxFieldLength.UNLIMITED);
    
    
                DataSet ds = DbHelperSQL.Query("select * from dbo.Sentences", 100);
                DataTable dt = ds.Tables[0];
                int rowsCount = dt.Rows.Count;
                for (int n = 0; n < rowsCount; n++)
                {
    
                    if (dt.Rows[n]["Id"].ToString() != "" && dt.Rows[n]["TextZh"].ToString() != "")
                    {
                        //--------------------------------遍历数据源 将数据转换成为文档对象 存入索引库
                        Document document = new Document(); //new一篇文档对象 --一条记录相应索引库中的一个文档
    
                        //向文档中加入字段  Add(字段,值,是否保存字段原始值,是否针对该列创建索引)
                        document.Add(new Field("id", dt.Rows[n]["Id"].ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));//--全部字段的值都将以字符串类型保存 由于索引库仅仅存储字符串类型数据
    
                        //Field.Store:表示是否保存字段原值。

    指定Field.Store.YES的字段在检索时才干用document.Get取出原值 //Field.Index.NOT_ANALYZED:指定不依照分词后的结果保存--是否按分词后结果保存取决于是否对该列内容进行模糊查询 document.Add(new Field("TextZh", dt.Rows[n]["TextZh"].ToString(), Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); //Field.Index.ANALYZED:指定文章内容依照分词后结果保存 否则无法实现兴许的模糊查询 //WITH_POSITIONS_OFFSETS:指示不仅保存切割后的词 还保存词之间的距离 //document.Add(new Field("content", "我常常出去玩", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS)); writer.AddDocument(document); //文档写入索引库 Console.Write("{0} ", n+1); } } writer.Close();//会自己主动解锁 directory.Close(); //不要忘了Close,否则索引结果搜不到 } public static void Query(string strQuery) { Stopwatch sw = new Stopwatch(); sw.Start(); FSDirectory directory = FSDirectory.Open(new DirectoryInfo("CH-EG"), new NoLockFactory()); IndexReader reader = IndexReader.Open(directory, true); IndexSearcher searcher = new IndexSearcher(reader); //搜索条件 PhraseQuery query = new PhraseQuery(); //把用户输入的关键字进行分词 foreach(string word in SplitWords(strQuery)) { query.Add(new Term("TextZh", word)); } //query.Add(new Term("content", "C#"));//多个查询条件时 为且的关系 query.SetSlop(100); //指定关键词相隔最大距离 //TopScoreDocCollector盛放查询结果的容器 TopScoreDocCollector collector = TopScoreDocCollector.create(1000, true); searcher.Search(query, null, collector);//依据query查询条件进行查询,查询结果放入collector容器 sw.Stop(); //TopDocs 指定0到GetTotalHits() 即全部查询结果中的文档 假设TopDocs(20,10)则意味着获取第20-30之间文档内容 达到分页的效果 ScoreDoc[] docs = collector.TopDocs(0, collector.GetTotalHits()).scoreDocs; //展示数据实体对象集合 for (int i = 0; i < docs.Length; i++) { int docId = docs[i].doc;//得到查询结果文档的id(Lucene内部分配的id) Document doc = searcher.Doc(docId);//依据文档id来获得文档对象Document Console.Write("{0} ", doc.Get("TextZh")); } TimeSpan ts2 = sw.Elapsed; Console.WriteLine("本次查询总共花费{0}ms. ", ts2.TotalMilliseconds); } static void Main(string[] args) { //CreateIndex("CH-EG"); Console.Write("Press phrase: "); string strQuery = Console.ReadLine(); while (strQuery != "") { Query(strQuery); Console.Write("Press phrase: "); strQuery = Console.ReadLine(); } } } }

    Demo下载地址 http://download.csdn.net/detail/lampqiu/8909427

  • 相关阅读:
    信息安全从业人员出路在哪里?
    内网渗透总结
    google hack使用集锦
    几十万学费总结出来的Ddos攻击防护经验!
    thinkPHP渗透之经验决定成败
    查找文件是否存在,文件属性、日期、大小;
    RS232/485通信方式 保存和加载时数据的处理
    memcpy(&pData[nDataLen],PROGDATA_FILE_FRAM,strlen(PROGDATA_FILE_FRAM)) ;
    #define BREAKIFTRUE( ret ) if( ( ret ) ) break;
    cp5200的一般步骤
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/7140720.html
Copyright © 2011-2022 走看看