這裏個人的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; } } }
二、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(); } } }
三、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);//建立索引 } } }
四、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; } } }
五、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; } } }
六、Models文件夾下的ThirdInfo以下:
namespace LuceneNetTest.Models { public class ThirdInfo { public string Id { get; set; } public string Name { get; set; } public string Taxnum { get; set; } } }
七、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; } } } }
十、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(); } } }
十一、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; } } }
上面簡單的實現了搜索。