久久精品水蜜桃av综合天堂,久久精品丝袜高跟鞋,精品国产肉丝袜久久,国产一区二区三区色噜噜,黑人video粗暴亚裔

SPB-設(shè)計(jì)機(jī)制-全文檢索

來(lái)自站長(zhǎng)百科
跳轉(zhuǎn)至: 導(dǎo)航、? 搜索

導(dǎo)航: 上一頁(yè)

全文檢索在SpaceBuilder中有兩個(gè)重要的作用:

  1. 所有模糊搜索都采用全文檢索實(shí)現(xiàn),減輕數(shù)據(jù)庫(kù)的負(fù)擔(dān);
  2. 實(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)題。

Spacebuilder097.jpg

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" />
  1. globalIndexDirectory表示所有索引文件的根目錄,可以是虛擬路徑(~/IndexFiles/),也可以是物理路徑(e:\SpaceBuilderIndex\ 或者 \\192.168.0.1\SpaceBuilderIndex\)。
  2. )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ì)得到比較好的索引效果。
  3. minMergeDocs表示最小合并文檔數(shù),這個(gè)參數(shù)也會(huì)影響索引的性能。它決定了內(nèi)存中的文檔數(shù)至少達(dá)到多少才能將它們寫(xiě)回磁盤(pán)。這個(gè)參數(shù)的默認(rèn)值是,如果你有足夠的內(nèi)存,那么將這個(gè)值盡量設(shè)的比較大一些將會(huì)顯著的提高索引性能。
  4. 索引文件格式目前SpaceBuilder內(nèi)置了兩部分索引文件:一部分是針對(duì)個(gè)人用戶的索引,另一部分是Post(包括:博客文章、圖片、文件、網(wǎng)摘、資訊等)。如果新加的應(yīng)用可以直接使用Post索引,則可以省去建立索引文件格式的工作量,只需確定好Post索引的對(duì)應(yīng)關(guān)系。否則,需要建立新加應(yīng)用的索引文件格式。
  5. 開(kāi)發(fā)新加應(yīng)用的ExtensionModules及Task;
  6. 開(kāi)發(fā)新加應(yīng)用的FullTextQuery(查詢條件)及Search(查詢器);例如:SpaceBuilder.File.FileThreadFullTextQuery及SpaceBuilder.LuceneSearch.FileSearch。


參考資料[ ]