使用Lucene.net+盤古分詞實現搜索查詢

                           這裏個人的Demo的邏輯是這樣的:首先我基本的數據是儲存在Sql數據庫中,而後我把個人必需的數據推送到MongoDB中,這樣再去利用Lucene.net+盤古建立索引;其中爲何要這樣把數據推送到MongoDb中,個人理解是能夠從Sql中直接取出來必需的數據,首次推送多是要推送全部的數據,直接建立索引,可是在第二次推送的時候,可能存在要修改或者新增的數據,這樣咱們就須要一箇中間表,而這個中間表咱們是使用的MongoDB文件型存儲來處理啦,而沒在sql數據庫中在創建一張表,我是這麼理解的。。。大致上的邏輯是這樣的,下面簡單寫一個實現的邏輯。算法

          細微的說下程序的邏輯以下:sql

          一、第一次推數據,把全部的數據推送到mongo,並且第一次搜索的話只能在元數據的list上取數據創建索引
          二、第二次推數據:首先對比mongo,若是mongo裏面有要新增或者修改的數據,更新mongo,而後再推送lucene中mongodb

          查詢數據:一、若是查詢出來的list爲空,則從第三方查詢,分別有2個連接,若是爲空則爲空,若是不爲空,則查詢出來的數據存放在MongoDB,推送Lucene.net中便可。數據庫

         1、準備工做express

         首先我這裏建立了一個控制檯程序,而後引用在NuGet包中添加以下須要安裝的dll,以下:json

                           

                          

                         2、Demo結構以下: api

                         

                         3、代碼以下:服務器

                         一、Helper文件夾下的BizLogger以下:app

using NLog;
using System;

namespace LuceneNetTest
{
    /// <summary>
    /// 業務日誌記錄器
    /// </summary>
    public class BizLogger
    {
        protected Logger _Logger { get; set; }

        public static BizLogger Default { get; protected set; }

        protected BizLogger(Logger logger)
        {
            this._Logger = logger;
        }

        public BizLogger(string name) : this(LogManager.GetLogger(name)) { }

        /// <summary>
        /// 靜態構造函數
        /// </summary>
        static BizLogger()
        {
            Default = new BizLogger(LogManager.GetCurrentClassLogger());
        }

        public void Debug(string message, params object[] args)
        {
            this._Logger.Debug(this.getMessage(message), args);
        }

        public void Info(string message, params object[] args)
        {
            this._Logger.Info(this.getMessage(message), args);
        }

        public void Trace(string message, params object[] args)
        {
            this._Logger.Trace(this.getMessage(message), args);
        }

        public void Error(string message, params object[] args)
        {
            this._Logger.Error(this.getMessage(message), args);
        }

        public void Fatal(string message, params object[] args)
        {
            this._Logger.Fatal(this.getMessage(message), args);
        }

        public void Debug(Exception exception, string message, params object[] args)
        {
            this._Logger.Log(LogLevel.Debug, exception, this.getMessage(message), args);
        }

        public void Info(Exception exception, string message, params object[] args)
        {
            this._Logger.Log(LogLevel.Info, exception, this.getMessage(message), args);
        }

        public void Trace(Exception exception, string message, params object[] args)
        {
            this._Logger.Log(LogLevel.Trace, exception, this.getMessage(message), args);
        }

        public void Error(Exception exception, string message, params object[] args)
        {
            this._Logger.Log(LogLevel.Error, exception, this.getMessage(message), args);
        }

        public void Fatal(Exception exception, string message, params object[] args)
        {
            this._Logger.Log(LogLevel.Fatal, exception, this.getMessage(message), args);
        }

        protected virtual string getMessage(string message)
        {
            return message;
        }
    }
}
View Code

                         二、Helper文件夾下的DataSerializer以下:異步

using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace LuceneNetTest
{
    /// <summary>
    /// 數據序列化器
    /// </summary>
    public static class DataSerializer
    {
        /// <summary>
        /// json 序列號
        /// </summary>
        /// <param name="source">要序列化的對象</param>
        /// <param name="b">是否忽略空值,true爲不忽略</param>
        /// <returns></returns>
        public static string SerizlizeToJSON(object source, bool b = true)
        {
            var setting = new JsonSerializerSettings();
            setting.ContractResolver = new SortedContractResolver();
            if (!b)
            {
                setting.NullValueHandling = NullValueHandling.Ignore; //忽略空對象 
            }
            var jsonString = JsonConvert.SerializeObject(source, setting);

            return jsonString;
        }

        public static TData DeserializeFromJSON<TData>(string jsonString)
        {
            var data = JsonConvert.DeserializeObject<TData>(jsonString);
            return data;
        }
    }

    public class SortedContractResolver : DefaultContractResolver
    {
        protected override List<MemberInfo> GetSerializableMembers(Type objectType)
        {
            var members = base.GetSerializableMembers(objectType);

            return members.OrderBy(m => m.Name).ToList();
        }
    }
}
View Code

                         三、Helper文件夾下的LuceneNetTestHelpers以下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using LuceneNetTest.Models;

namespace LuceneNetTest.Helpers
{
    /// <summary>
    /// 數據處理
    /// </summary>
    public static class LuceneNetTestHelpers
    {
        /// <summary>
        /// 從sql數據庫中獲取全部的數據,推送到mongodb中
        /// </summary>
        /// <returns>全部的數據list</returns>
        public static List<LuceneTestData> GetSqlData()
        {
            #region 第一次推送數據到mogodb

            List<LuceneTestData> invList = new List<LuceneTestData>();//建立索引的集合
            return invList;

            #endregion
        }

        /// <summary>
        /// mongodb數據庫中的數據和新查詢出來的數據進項對比,
        /// 若是有須要修改和須要新增的數據及修改mongodb,
        /// 這裏爲lucene建立索引奠基基礎(state的狀態爲y即爲新增,n表示修改)
        /// </summary>
        /// <param name="invList">查詢出來的sql數據</param>
        public static string GetMongoDBData(List<LuceneTestData> invList)
        {
            var result = string.Empty;
            MongoDbHelper<LuceneTestData> mgTwo = new MongoDbHelper<LuceneTestData>();
            var exsitList = mgTwo.QueryAll();//取出來mongodb中的數據

            #region 第二次之後推送數據
            try
            {
                foreach (var inv in invList)//遍歷元數據庫
                {
                    //若是存在就對比是否同樣,不同的話更新mongodb
                    if (exsitList.Any(n => n.Id == inv.Id))
                    {
                        var oldInvoice = exsitList.FirstOrDefault(n => n.Id == inv.Id);
                        if (oldInvoice.Name != inv.Name || oldInvoice.Code != inv.Code || oldInvoice.AddressPhone != inv.AddressPhone || oldInvoice.BankAccount != inv.BankAccount)
                        {
                            oldInvoice.Name = inv.Name;
                            oldInvoice.Code = inv.Code;
                            oldInvoice.AddressPhone = inv.AddressPhone;
                            oldInvoice.BankAccount = inv.BankAccount;
                            oldInvoice.State = "n";
                            inv.CreateTime = DateTime.Now.ToString();
                            inv.UpdateTime = "";

                            mgTwo.Update(oldInvoice);
                        }
                    }
                    else
                    {
                        var newInvoice = new LuceneTestData();
                        newInvoice.Name = inv.Name;
                        newInvoice.Code = inv.Code;
                        newInvoice.AddressPhone = inv.AddressPhone;
                        newInvoice.BankAccount = inv.BankAccount;
                        newInvoice.State = "y";
                        newInvoice.CreateTime = DateTime.Now.ToString();
                        newInvoice.UpdateTime = "";
                        mgTwo.InsertOne(newInvoice);//若是不存在就直接插入操做
                    }
                }
                return "";
            }
            catch(Exception ex)
            {
                return ex.Message;
            }

            #endregion

        }

        /// <summary>
        /// 請求第三方數據
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static string RequestData(string name)
        {
            byte[] bufferStr = System.Text.Encoding.Default.GetBytes(name);
            //api的url
            StringBuilder InvoiceRequestUrl = new StringBuilder();
            InvoiceRequestUrl.Append("。。。。。。。。。。。。。。");
            InvoiceRequestUrl.Append(name);
            InvoiceRequestUrl.Append("。。。。。。。。。。。");
            string strResult = PostReauest(bufferStr, InvoiceRequestUrl.ToString());
            return strResult;
        }

        /// <summary>
        /// 請求第三方數據
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static string RequestData2(string name)
        {
            byte[] bufferStr = System.Text.Encoding.Default.GetBytes(name);
            //api的url
            StringBuilder InvoiceRequestUrl = new StringBuilder();
            InvoiceRequestUrl.Append("。。。。。。。。。。。。。。。。。。");
            InvoiceRequestUrl.Append(name);
            InvoiceRequestUrl.Append("。。。。。。。。。。。。。。。。");
            string strResult = PostReauest(bufferStr, InvoiceRequestUrl.ToString());
            return strResult;
        }

        /// <summary>
        /// 請求第三方獲取搜索結果
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="requestUri"></param>
        /// <returns></returns>
        public static string PostReauest(byte[] buffer, string requestUri)
        {
            //請求遠程HTTP
            string strResult = "";
            Encoding code = Encoding.GetEncoding("utf-8");
            try
            {
                //設置HttpWebRequest基本信息
                HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(requestUri);
                myReq.Method = "post";
                myReq.ContentType = "application / json";

                //填充POST數據
                myReq.ContentLength = buffer.Length;
                Stream requestStream = myReq.GetRequestStream();
                requestStream.Write(buffer, 0, buffer.Length);
                requestStream.Close();

                //發送POST數據請求服務器
                HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
                Stream myStream = HttpWResp.GetResponseStream();

                //獲取服務器返回信息
                StreamReader reader = new StreamReader(myStream, code);
                StringBuilder responseData = new StringBuilder();
                String line;
                while ((line = reader.ReadLine()) != null)
                {
                    responseData.Append(line);
                }

                //釋放
                myStream.Close();

                strResult = responseData.ToString();
            }
            catch (Exception exp)
            {
                strResult = "報錯:" + exp.Message;
            }
            return strResult;
        }

        /// <summary>
        /// 第三方結果添加到mongodb中
        /// </summary>
        /// <param name="thirdInvoice">須要添加的第三數據</param>
        /// <param name="path">建立索引 </param>
        /// <param name="IndexDic"></param>
        public static void InThirdInfoToMongoAndLucene(List<ThirdInfo> thirdInvoice,string path,string IndexDic)
        {
            List<LuceneTestData> invList = new List<LuceneTestData>();
            foreach (var item in thirdInvoice)
            {
                var newInvoice = new LuceneTestData();
                newInvoice.Name = item.Name;
                newInvoice.State = "y";
                newInvoice.CreateTime = DateTime.Now.ToString();
                newInvoice.UpdateTime = "";
                invList.Add(newInvoice);
            }
            MongoDbHelper<LuceneTestData> mg = new MongoDbHelper<LuceneTestData>();
            mg.InsertBatch(invList);
            PanGuLuceneHelper.InitPanGuXmlPath(path);
            PanGuLuceneHelper.CreateIndex(IndexDic, invList);//建立索引
        }

        /// <summary>
        /// 第三方結果添加到mongodb中
        /// </summary>
        /// <param name="thirdInvoice">須要添加的第三數據</param>
        /// <param name="path">建立索引 </param>
        /// <param name="IndexDic"></param>
        public static void InThirdTestInfoToMongoAndLucene(List<ThirdTestInfo> elephantHuiYun, string path, string IndexDic)
        {
            List<LuceneTestData> invList = new List<LuceneTestData>();
            foreach (var item in elephantHuiYun)
            {
                var newInvoice = new LuceneTestData();
                newInvoice.Name = item.Nsrmc;
                newInvoice.State = "y";
                newInvoice.CreateTime = DateTime.Now.ToString();
                newInvoice.UpdateTime = "";
                invList.Add(newInvoice);
            }
            MongoDbHelper<LuceneTestData> mg = new MongoDbHelper<LuceneTestData>();
            mg.InsertBatch(invList);
            PanGuLuceneHelper.InitPanGuXmlPath(path);
            PanGuLuceneHelper.CreateIndex(IndexDic, invList);//建立索引
        }
    }
}
View Code

                          四、Helper文件夾下的MongoDbHelper以下:

using System;
using System.Collections.Generic;
using System.Linq;
using MongoDB.Bson;
using MongoDB.Driver;
using System.Linq.Expressions;
using System.Security.Authentication;

namespace LuceneNetTest.Helpers
{
    /// <summary>
    /// MongoDb幫助類
    /// </summary>
    public class DB
    {
        private static readonly string connStr = "mongodb://192.168.4.192:27017";
        private static readonly string dbName = "LuceneTestData";

        private static IMongoDatabase db = null;

        private static readonly object lockHelper = new object();

        private DB() { }

        public static IMongoDatabase GetDb()
        {
            if (db == null)
            {
                lock (lockHelper)
                {
                    if (db == null)
                    {
                        MongoClientSettings settings = MongoClientSettings.FromUrl(
                          new MongoUrl(connStr)
                        );
                        settings.SslSettings =
                          new SslSettings() { EnabledSslProtocols = SslProtocols.Tls12 };
                        var mongoClient = new MongoClient(settings);
                        db = mongoClient.GetDatabase(dbName);
                    }
                }
            }
            return db;
        }
    }

    public class MongoDbHelper<T> where T : BaseEntity
    {
        private IMongoDatabase db = null;

        private IMongoCollection<T> collection = null;

        public MongoDbHelper()
        {
            this.db = DB.GetDb();
            collection = db.GetCollection<T>(typeof(T).Name);
        }
        /// <summary>
        /// 新增,異步
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public T Insert(T entity)
        {
            var flag = ObjectId.GenerateNewId();
            entity.GetType().GetProperty("Id").SetValue(entity, flag);
            entity.State = "y";
            entity.CreateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            entity.UpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

            collection.InsertOne(entity);

            return entity;
        }

        /// <summary>
        /// 新增數據,同步
        /// </summary>
        /// <param name="entity">待存儲類對象</param>
        /// <returns></returns>
        public T InsertOne(T entity)
        {
            var flag = ObjectId.GenerateNewId();
            entity.GetType().GetProperty("Id").SetValue(entity, flag);
            entity.State = "y";
            entity.CreateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            entity.UpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

            collection.InsertOne(entity);

            return entity;
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="id"></param>
        /// <param name="field"></param>
        /// <param name="value"></param>
        public void Modify(string id, string field, string value)
        {
            var filter = Builders<T>.Filter.Eq("Id", ObjectId.Parse(id));
            var updated = Builders<T>.Update.Set(field, value);
            UpdateResult result = collection.UpdateOne(filter, updated);
        }
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="entity"></param>
        public void Update(T entity)
        {
            try
            {
                var old = collection.Find(e => e.Id.Equals(entity.Id)).ToList().FirstOrDefault();

                foreach (var prop in entity.GetType().GetProperties())
                {
                    var newValue = prop.GetValue(entity);
                    var oldValue = old.GetType().GetProperty(prop.Name).GetValue(old);
                    if (newValue != null)
                    {
                        if (oldValue == null)
                            oldValue = "";
                        if (!newValue.ToString().Equals(oldValue.ToString()))
                        {
                            old.GetType().GetProperty(prop.Name).SetValue(old, newValue.ToString());
                        }
                    }
                }
                old.State = "n";
                old.UpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

                var filter = Builders<T>.Filter.Eq("Id", entity.Id);
                ReplaceOneResult result = collection.ReplaceOne(filter, old);
            }
            catch (Exception ex)
            {
                var aaa = ex.Message + ex.StackTrace;
                throw ex;
            }
        }
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="entity"></param>
        public void UpdateEx(T entity)
        {
            try
            {
                var old = collection.Find(e => e.Id.Equals(entity.Id)).ToList().FirstOrDefault();

                foreach (var prop in entity.GetType().GetProperties())
                {
                    var newValue = prop.GetValue(entity);
                    var oldValue = old.GetType().GetProperty(prop.Name).GetValue(old);
                    if (newValue != null)
                    {
                        if (oldValue == null)
                            oldValue = "";
                        if (!newValue.ToString().Equals(oldValue.ToString()))
                        {
                            old.GetType().GetProperty(prop.Name).SetValue(old, newValue);
                        }
                    }
                }
                old.State = "n";
                old.UpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

                var filter = Builders<T>.Filter.Eq("Id", entity.Id);
                ReplaceOneResult result = collection.ReplaceOne(filter, old);
            }
            catch (Exception ex)
            {
                var aaa = ex.Message + ex.StackTrace;
                throw ex;
            }
        }
        /// <summary>
        /// 刪除,異步
        /// </summary>
        /// <param name="entity">刪除對象</param>
        public void Delete(T entity)
        {
            var filter = Builders<T>.Filter.Eq("Id", entity.Id);
            collection.DeleteOne(filter);
        }

        /// <summary>
        /// 刪除,同步
        /// </summary>
        /// <param name="Id">刪除對象Id</param>
        /// <returns></returns>
        public long Delete(string IdString)
        {
            ObjectId Id = ObjectId.Parse(IdString);

            var filter = Builders<T>.Filter.Eq("Id", Id);
            var rt = collection.DeleteOne(filter);
            return rt.DeletedCount;
        }
        /// <summary>
        /// 根據id查詢一條數據
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public T QueryOne(string id)
        {
            return collection.Find(a => a.Id == ObjectId.Parse(id)).ToList().FirstOrDefault();
        }
        /// <summary>
        /// 查詢全部數據
        /// </summary>
        /// <returns></returns>
        public List<T> QueryAll()
        {
            return collection.Find(a => a.State != "").ToList();
        }
        /// <summary>
        /// 根據條件查詢一條數據
        /// </summary>
        /// <param name="express"></param>
        /// <returns></returns>
        public T QueryByFirst(Expression<Func<T, bool>> express)
        {
            return collection.Find(express).ToList().FirstOrDefault();
        }
        /// <summary>
        /// 根據條件查詢數據
        /// </summary>
        /// <param name="express"></param>
        /// <returns></returns>
        public List<T> QueryBy(Expression<Func<T, bool>> express)
        {
            return collection.Find(express).ToList();
        }
        /// <summary>
        /// 批量添加
        /// </summary>
        /// <param name="list"></param>
        public void InsertBatch(List<T> list)
        {
            collection.InsertMany(list);
        }
        /// <summary>
        /// 根據Id批量刪除
        /// </summary>
        public void DeleteBatch(List<ObjectId> list)
        {
            var filter = Builders<T>.Filter.In("Id", list);
            collection.DeleteMany(filter);
        }

        /// <summary>
        /// 未添加到索引的數據
        /// </summary>
        /// <returns></returns>
        public List<T> QueryToLucene()
        {
            return collection.Find(a => a.State.Equals("y") || a.State.Equals("n")).ToList();
        }
    }
    public abstract class BaseEntity
    {
        /// <summary>
        /// 對象存儲Id,數據庫賦值
        /// </summary>
        public ObjectId Id { get; set; }

        /// <summary>
        /// 狀態值,可自行決定使用性質
        /// </summary>
        public string State { get; set; }

        /// <summary>
        /// 建立時間
        /// </summary>
        public string CreateTime { get; set; }

        /// <summary>
        /// 修改時間
        /// </summary>
        public string UpdateTime { get; set; }
    }
}
View Code

                          五、Models文件夾下的LuceneTestData以下:

using LuceneNetTest.Helpers;

namespace LuceneNetTest.Models
{
    public class LuceneTestData : BaseEntity
    {
        public string Name { get; set; }
        public string Code { get; set; }
        public string AddressPhone { get; set; }
        public string BankAccount { get; set; }
    }
}
View Code

                          六、Models文件夾下的ThirdInfo以下:

namespace LuceneNetTest.Models
{
    public class ThirdInfo
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string Taxnum { get; set; }
    }
}
View Code

                          七、Models文件夾下的ThirdTestData用戶請求第三方數據反序列化解析數據,暫不展現

                       八、PanGu文件夾下是盤古分詞,這裏下載添加便可。

                       九、PanGuLuceneHelper以下:

using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.Analysis;
using System.Collections.Generic;
using System.IO;
using Lucene.Net.Search;
using System;
using Lucene.Net.Store;
using Lucene.Net.QueryParsers;
using LuceneNetTest.Models;
using LuceneNetTest.Helpers;
using MongoDB.Bson;

namespace LuceneNetTest
{
    /// <summary>
    /// 信息
    /// </summary>
    public class PanGuLuceneHelper
    {

        public static Analyzer analyzer = new PanGuAnalyzer();//指定使用盤古 PanGuAnalyzer 分詞算法

        /// <summary>
        /// 初始化盤古分詞的xml引用路徑
        /// </summary>
        /// <param name="PanGuXmlPath"></param>
        public static void InitPanGuXmlPath(string PanGuXmlPath)
        {
            //定義盤古分詞的xml引用路徑
            PanGu.Segment.Init(PanGuXmlPath);
        }

        /// <summary>
        /// 建立索引
        /// </summary>
        /// <param name="IndexDic">目錄地址</param>
        /// <param name="isCreate">是否從新建立</param>
        public static Result CreateIndex(string IndexDic,List<LuceneTestData> list = null)
        {
            IndexWriter writer;
            var result = new Result();
            try
            {
                //建立索引目錄
                FSDirectory directory = FSDirectory.Open(new DirectoryInfo(IndexDic), new NativeFSLockFactory());
                //IndexReader:對索引庫進行讀取的類
                //是否存在索引庫文件夾以及索引庫特徵文件
                //若是索引目錄被鎖定(好比索引過程當中程序異常退出或另外一進程在操做索引庫),則解鎖
                if (IndexWriter.IsLocked(directory))
                {
                    IndexWriter.Unlock(directory);
                }
                //IndexWriter第三個參數:true指從新建立索引,false指從當前索引追加....此處爲新建索引因此爲true
                writer = new IndexWriter(directory, analyzer, Lucene.Net.Index.IndexWriter.MaxFieldLength.LIMITED);
                AddIndex(writer, list);
                writer.Optimize();
                writer.Dispose();
                result = new Result()
                {
                    Success = true
                };
            }
            catch (Exception ex)
            {
                result = new Result()
                {
                    Success = false,
                    Message = ex.Message
                };
            }
            return result;
        }

        /// <summary>
        /// 建立索引
        /// </summary>
        /// <param name="analyzer"></param>
        /// <param name="title"></param>
        /// <param name="content"></param>
        private static void AddIndex(IndexWriter writer, List<LuceneTestData> list = null)
        {
            try
            {
                //for (int i = 0; i < 10; i++)
                //{
                //    Document doc = new Document();
                //    doc.Add(new Field("Name", "大賁科技" + i, Field.Store.YES, Field.Index.ANALYZED));//存儲且索引
                //    writer.AddDocument(doc);
                //}
                MongoDbHelper<LuceneTestData> mg = new MongoDbHelper<LuceneTestData>();
                var customerList = mg.QueryToLucene();
                if (list != null)
                {
                    customerList = list;
                }
                foreach (var item in customerList)
                {
                    Document doc = new Document();
                    doc.Add(new Field("Name", item.Name == null ? "" : item.Name, Field.Store.YES, Field.Index.ANALYZED));//存儲且索引
                    doc.Add(new Field("TaxCode", item.Code == null ? "" : item.Code, Field.Store.YES, Field.Index.ANALYZED));//存儲且索引
                    doc.Add(new Field("AddressPhone", item.AddressPhone == null ? "" : item.AddressPhone, Field.Store.YES, Field.Index.NOT_ANALYZED));//存儲且索引
                    doc.Add(new Field("BankAccount", item.BankAccount == null ? "" : item.BankAccount, Field.Store.YES, Field.Index.NOT_ANALYZED));//存儲且索引
                    doc.Add(new Field("State", item.State, Field.Store.YES, Field.Index.NOT_ANALYZED));//存儲且索引
                    doc.Add(new Field("Id", item.Id.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));//存儲且索引
                    doc.Add(new Field("CreateTime", item.CreateTime.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));//存儲且索引
                    doc.Add(new Field("UpdateTime", item.UpdateTime.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));//存儲且索引

                    if (item.State == "n")//修改
                    {
                        Term t = new Term("Id", item.Id.ToString());
                        writer.DeleteDocuments(t);
                        writer.AddDocument(doc);
                    }
                    else if (item.State == "y")//新增
                    {
                        writer.AddDocument(doc);
                    }
                    //修改mongodb狀態爲ok,下次就不操做到索引了。
                    mg.Modify(item.Id.ToString(), "State", "ok");
                }
            }
            catch (FileNotFoundException fnfe)
            {
                throw fnfe;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 建立索引
        /// </summary>
        /// <param name="analyzer"></param>
        /// <param name="title"></param>
        /// <param name="content"></param>
        private static void AddIndexNew(IndexWriter writer)
        {
            try
            {
                MongoDbHelper<LuceneTestData> mg = new MongoDbHelper<LuceneTestData>();
                var customerList = mg.QueryToLucene();
                foreach (var item in customerList)
                {
                    Document doc = new Document();
                    doc.Add(new Field("Name", item.Name == null ? "" : item.Name, Field.Store.YES, Field.Index.ANALYZED));//存儲且索引
                    doc.Add(new Field("TaxCode", item.Code == null ? "" : item.Code, Field.Store.YES, Field.Index.ANALYZED));//存儲且索引
                    doc.Add(new Field("AddressPhone", item.AddressPhone == null ? "" : item.AddressPhone, Field.Store.YES, Field.Index.NOT_ANALYZED));//存儲且索引
                    doc.Add(new Field("BankAccount", item.BankAccount == null ? "" : item.BankAccount, Field.Store.YES, Field.Index.NOT_ANALYZED));//存儲且索引
                    doc.Add(new Field("State", item.State, Field.Store.YES, Field.Index.NOT_ANALYZED));//存儲且索引
                    doc.Add(new Field("Id", item.Id.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));//存儲且索引
                    doc.Add(new Field("CreateTime", item.CreateTime.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));//存儲且索引
                    doc.Add(new Field("UpdateTime", item.UpdateTime.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));//存儲且索引

                    if (item.State == "n")//修改
                    {
                        Term t = new Term("Id", item.Id.ToString());
                        writer.DeleteDocuments(t);
                        writer.AddDocument(doc);
                    }
                    else if (item.State == "y")//新增
                    {
                        writer.AddDocument(doc);
                    }
                    //修改mongodb狀態爲ok,下次就不操做到索引了。
                    mg.Modify(item.Id.ToString(), "State", "ok");
                }
            }
            catch (FileNotFoundException fnfe)
            {
                throw fnfe;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 分詞方法
        /// </summary>
        /// <param name="words">待分詞內容</param>
        /// <param name="analyzer"></param>
        /// <returns></returns>
        private static string cutWords(string words, Analyzer analyzer)
        {
            string resultStr = "";
            System.IO.StringReader reader = new System.IO.StringReader(words);
            Lucene.Net.Analysis.TokenStream ts = analyzer.TokenStream(words, reader);
            bool hasNext = ts.IncrementToken();
            Lucene.Net.Analysis.Tokenattributes.ITermAttribute ita;
            while (hasNext)
            {
                ita = ts.GetAttribute<Lucene.Net.Analysis.Tokenattributes.ITermAttribute>();
                resultStr += ita.Term + "|";
                hasNext = ts.IncrementToken();
            }
            ts.CloneAttributes();
            reader.Close();
            analyzer.Close();
            return resultStr;
        }

        /// <summary>
        /// 從索引搜索結果
        /// </summary>
        public static List<LuceneTestData> SearchIndex(string content, string IndexDic)
        {
            try
            {
                var str = cutWords(content, analyzer);
                FSDirectory directory = FSDirectory.Open(new DirectoryInfo(IndexDic), new NoLockFactory());
                IndexReader reader = IndexReader.Open(directory, true);
                IndexSearcher search = new IndexSearcher(directory, true);

                //建立查詢
                PerFieldAnalyzerWrapper wrapper = new PerFieldAnalyzerWrapper(analyzer);
                wrapper.AddAnalyzer("Name", analyzer);
                QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, "Name", wrapper);
                Query query = parser.Parse(content);
                TopScoreDocCollector collector = TopScoreDocCollector.Create(4, true);//10--默認查詢4條數

                BooleanQuery bQuery = new BooleanQuery();
                bQuery.Add(query, new Occur());
                search.Search(bQuery, collector);
                var hits = collector.TopDocs().ScoreDocs;

                int numTotalHits = collector.TotalHits;

                List<LuceneTestData> list = new List<LuceneTestData>();
                for (int i = 0; i < hits.Length; i++)
                {
                    var hit = hits[i];
                    Document doc = search.Doc(hit.Doc);

                    var model = new LuceneTestData()
                    {
                        Name = doc.Get("Name").ToString(),
                        Code = doc.Get("TaxCode").ToString(),
                        AddressPhone = doc.Get("AddressPhone").ToString(),
                        BankAccount = doc.Get("BankAccount").ToString(),
                        State = doc.Get("State").ToString(),
                        Id = ObjectId.Parse(doc.Get("Id")),
                        CreateTime = doc.Get("CreateTime").ToString(),
                        UpdateTime = doc.Get("UpdateTime").ToString()
                    };
                    list.Add(model);
                }
                return list;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}
View Code

                          十、Program以下:

using System;
using System.Collections.Generic;
using System.Linq;
using LuceneNetTest.Models;
using LuceneNetTest.Helpers;

namespace LuceneNetTest
{
    class Program
    {
        //一、第一次推數據,把全部的數據推送到mongo,並且第一次搜索的話只能在元數據的list上取數據創建索引
        //二、第二次推數據:首先對比mongo,若是mongo裏面有要新增或者修改的數據,更新mongo,而後再推送lucene中

        //查詢數據:一、若是查詢出來的list爲空,則從第三方查詢,分別有2個連接,若是爲空則爲空,若是不爲空,
        //則查詢出來的數據存放在mongo中,推送到lucene中
        static void Main(string[] args)
        {
            var IndexDic = @"C:/Users/Administrator/Desktop/RSA/LuceneNetTest/IndexDic/IndexDic";//索引建立的地址
            var path = @"C:/Users/Administrator/Desktop/RSA/LuceneNetTest/PanGu/PanGu.xml";//盤古分詞地址
            List<LuceneTestData> invList = LuceneNetTestHelpers.GetSqlData();
            BizLogger.Default.Info($"初次獲取信息數據,總共獲取了{invList.Count}條。");

            #region  第一次推送數據到mogodb

            MongoDbHelper<LuceneTestData> mg = new MongoDbHelper<LuceneTestData>();
            mg.InsertBatch(invList);
            BizLogger.Default.Info($"信息數據推送到MongoDB數據庫完成,總共獲取了{invList.Count}條。");
            PanGuLuceneHelper.InitPanGuXmlPath(path);
            PanGuLuceneHelper.CreateIndex(IndexDic, invList);//建立索引
            BizLogger.Default.Info($"信息數據初次建立索引成功,總共建立了{invList.Count}條數據。");

            #endregion

            #region 第二次推送數據到mogodb

            //取出來本次查詢的sql數據與mongodb數據庫中的數據是否有差異。。。
            string result = LuceneNetTestHelpers.GetMongoDBData(invList);
            BizLogger.Default.Info($"從SQL數據庫獲取信息與MongoDB數據信息進行對比,總共獲取了{invList.Count}條。");
            //var IndexDic = AppDomain.CurrentDomain.BaseDirectory + "/IndexDic";
            if (string.IsNullOrEmpty(result))
            {
                PanGuLuceneHelper.InitPanGuXmlPath(path);
                PanGuLuceneHelper.CreateIndex(IndexDic);//建立索引
                BizLogger.Default.Info($"信息建立索引成功");
            }

            #endregion

            #region 搜索

            string name = "上海";
            var list = PanGuLuceneHelper.SearchIndex(name, IndexDic);//搜索查詢
            if (list == null)
            {
                //第一次請求第三方(諾諾:用的航信的)
                string strResult = LuceneNetTestHelpers.RequestData(name);
                if (!string.IsNullOrEmpty(strResult))
                {
                    List<ThirdInfo> thirdInfo = DataSerializer.DeserializeFromJSON<List<ThirdInfo>>(strResult);
                    //更新mongodb數據庫餅更新建立索引
                    LuceneNetTestHelpers.InThirdInfoToMongoAndLucene(thirdInfo, path, IndexDic);
                    BizLogger.Default.Info($"從第三方。。中獲取信息更新到MongoDB成功,而且建立索引成功");
                    //反序列化結果
                    Console.WriteLine(string.Join("", thirdInfo.Select(t => t.Name)));
                }
                else
                {
                    //第二次請求第三方(大象慧雲)
                    string twoResult = LuceneNetTestHelpers.RequestData2(name);
                    if (!string.IsNullOrEmpty(twoResult))
                    {
                        //同上請求第三方
                    }
                    else
                    {
                        Console.WriteLine("暫無信息");
                    }
                }
            }

            #endregion

            Console.WriteLine(string.Join("", list.Select(n => n.Name)));
            Console.ReadKey();
        }
    }
}
 
View Code

                          十一、Result以下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LuceneNetTest
{
    public class Result
    {
        public bool Success { get; set; }

        public int StatusCode { get; set; }

        public string Message { get; set; }
    }
}
View Code

                          上面簡單的實現了搜索。

相關文章
相關標籤/搜索