WIKI使用導(dǎo)航
站長(zhǎng)百科導(dǎo)航
站長(zhǎng)專(zhuān)題
- 網(wǎng)站推廣
- 網(wǎng)站程序
- 網(wǎng)站賺錢(qián)
- 虛擬主機(jī)
- cPanel
- 網(wǎng)址導(dǎo)航專(zhuān)題
- 云計(jì)算
- 微博營(yíng)銷(xiāo)
- 虛擬主機(jī)管理系統(tǒng)
- 開(kāi)放平臺(tái)
- WIKI程序與應(yīng)用
- 美國(guó)十大主機(jī)
SPB-設(shè)計(jì)機(jī)制-全文檢索
來(lái)自站長(zhǎng)百科
導(dǎo)航: 上一頁(yè)
全文檢索在SpaceBuilder中有兩個(gè)重要的作用:
- 所有模糊搜索都采用全文檢索實(shí)現(xiàn),減輕數(shù)據(jù)庫(kù)的負(fù)擔(dān);
- 實(shí)現(xiàn)信息的挖掘,例如:資訊的相關(guān)資訊,博客文章的相關(guān)文章;
SpaceBuilder的全文檢索功能以Lucene.Net為核心。Lucene.Net是Apache Lucene的c#語(yǔ)言版本,Apache Lucene是一個(gè)開(kāi)源的搜索引擎,提供一組解讀,過(guò)濾,分析文件,編排和使用索引的API,它的強(qiáng)大之處除了高效和簡(jiǎn)單外,最重要的是使使用者可以隨時(shí)根據(jù)自己需要擴(kuò)展其功能。
一、索引文件同步機(jī)制
由于Lucene只能操作索引文件,而索引文件必須保證與數(shù)據(jù)庫(kù)數(shù)據(jù)同步。如何保證Lucene中索引文件與數(shù)據(jù)庫(kù)保持同步是一個(gè)必須要解決的問(wèn)題。
SpaceBuilder采用如下方式進(jìn)行解決:
- 建立spb_ItemsForIndex表,臨時(shí)保存需要更新到索引文件的數(shù)據(jù);
- 編寫(xiě)相應(yīng)的ExtensionModules,當(dāng)對(duì)象發(fā)生變化時(shí)記錄到spb_ItemsForIndex表中;
例如,SpaceBuilder.LuceneSearch.PrepareForUserIndexModule:
public class PrepareForUserIndexModule : IGlobalModule { #region IGlobalModule Members public void Init(GlobalEventManager gem, System.Xml.XmlNode node) { gem.AfterUserChange += new UserEventHandler(gem_PostUserUpdate); } #endregion void gem_PostUserUpdate(User user, GlobalEventArgs e) { if ((user != null) && (e.State == ObjectState.Create || e.State == ObjectState.Update || e.State == ObjectState.Delete)) { ItemForIndex item = new ItemForIndex(); item.ItemID = user.UserID; if (user.UserType == UserTypes.PersonUser) item.SearchType = FullTextSearchTypes.PersonUser; else if (user.UserType == UserTypes.CompanyUser) item.SearchType = FullTextSearchTypes.CompanyUser; item.DataAction = e.State; SearchDataProvider.Instance().CreateUpdateDeleteItemForIndex(item, DataProviderAction.Create); } } }
當(dāng)添加、修改、刪除用戶時(shí)將自動(dòng)記錄到spb_ItemsForIndex
- 編寫(xiě)相應(yīng)的Task,使spb_ItemsForIndex數(shù)據(jù)定期更新到Lucene索引文件中:
public class PersonUserIndexTask : ITask { /// <summary> /// 每次更新索引的最大數(shù)目 /// </summary> private int count = 1000; #region ITask Members public void Execute(System.Xml.XmlNode node) { XmlAttribute countNode = node.Attributes["count"]; if (countNode != null) { try { count = int.Parse(countNode.Value); } catch { count = 1000; } } SearchDataProvider dp = SearchDataProvider.Instance(); IList<ItemForIndex> itemsForIndex = dp.GetItemsForIndex(FullTextSearchTypes.PersonUser, count); IList<ItemForIndex> createItems = new List<ItemForIndex>(); IList<ItemForIndex> updateItems = new List<ItemForIndex>(); IList<ItemForIndex> deleteItems = new List<ItemForIndex>(); foreach (ItemForIndex item in itemsForIndex) { if (item.DataAction == ObjectState.Create) createItems.Add(item); else if (item.DataAction == ObjectState.Update) updateItems.Add(item); else if (item.DataAction == ObjectState.Delete) deleteItems.Add(item); } #region Insert IList<PersonUser> createUsers = new List<PersonUser>(); foreach (ItemForIndex item in createItems) { createUsers.Add((PersonUser)Users.GetUser(item.ItemID)); } if (PersonUserIndexServer.Insert(createUsers)) { dp.DeleteItemsForIndex(createItems); } else { foreach (ItemForIndex item in createItems) { item.DataAction = ObjectState.Update; } dp.UpdateItemsForIndex(createItems); } IList<PersonUser> updateUsers = new List<PersonUser>(); foreach (ItemForIndex item in updateItems) { updateUsers.Add((PersonUser)Users.GetUser(item.ItemID)); } if (PersonUserIndexServer.Update(updateUsers)) { dp.DeleteItemsForIndex(updateItems); } int[] deleteUids = new int[deleteItems.Count]; for (int i = 0; i < deleteItems.Count; i++) { deleteUids[i] = deleteItems[i].ItemID; } if (PersonUserIndexServer.Delete(deleteUids)) { dp.DeleteItemsForIndex(deleteItems); } } #endregion }
二、使用全文檢索
- 索引文件格式
- 索引文件配置
<LuceneSearch globalIndexDirectory="~/IndexFiles" mergeFactor="10" minMergeDocs="100" />
- globalIndexDirectory表示所有索引文件的根目錄,可以是虛擬路徑(~/IndexFiles/),也可以是物理路徑(e:\SpaceBuilderIndex\ 或者 \\192.168.0.1\SpaceBuilderIndex\)。
- )mergeFactor表示合并因子,這個(gè)參數(shù)決定了在 Lucene 的一個(gè)索引塊中可以存放多少文檔以及把磁盤(pán)上的索引塊合并成一個(gè)大的索引塊的頻率。比如,如果合并因子的值是 10,那么當(dāng)內(nèi)存中的文檔數(shù)達(dá)到 10 的時(shí)候所有的文檔都必須寫(xiě)到磁盤(pán)上的一個(gè)新的索引塊中。并且,如果磁盤(pán)上的索引塊的隔數(shù)達(dá)到 10 的話,這 10 個(gè)索引塊會(huì)被合并成一個(gè)新的索引塊。這個(gè)參數(shù)的默認(rèn)值是 10,如果需要索引的文檔數(shù)非常多的話這個(gè)值將是非常不合適的。對(duì)批處理的索引來(lái)講,為這個(gè)參數(shù)賦一個(gè)比較大的值會(huì)得到比較好的索引效果。
- minMergeDocs表示最小合并文檔數(shù),這個(gè)參數(shù)也會(huì)影響索引的性能。它決定了內(nèi)存中的文檔數(shù)至少達(dá)到多少才能將它們寫(xiě)回磁盤(pán)。這個(gè)參數(shù)的默認(rèn)值是,如果你有足夠的內(nèi)存,那么將這個(gè)值盡量設(shè)的比較大一些將會(huì)顯著的提高索引性能。
- 索引文件格式目前SpaceBuilder內(nèi)置了兩部分索引文件:一部分是針對(duì)個(gè)人用戶的索引,另一部分是Post(包括:博客文章、圖片、文件、網(wǎng)摘、資訊等)。如果新加的應(yīng)用可以直接使用Post索引,則可以省去建立索引文件格式的工作量,只需確定好Post索引的對(duì)應(yīng)關(guān)系。否則,需要建立新加應(yīng)用的索引文件格式。
- 開(kāi)發(fā)新加應(yīng)用的ExtensionModules及Task;
- 開(kāi)發(fā)新加應(yīng)用的FullTextQuery(查詢條件)及Search(查詢器);例如:SpaceBuilder.File.FileThreadFullTextQuery及SpaceBuilder.LuceneSearch.FileSearch。