从Sitecore的Lucene搜索索引中有选择地排除项目 – 在使用IndexViewer重建时有效,但在使用Sitecore的内置工具时无效

在由Sitecore 6.2提供支持的站点上,我需要让用户能够有选择地从搜索结果中排除项目。

为此,我添加了一个名为“包含在搜索结果中”的复选框字段,我创建了一个自定义数据库搜寻器来检查该字段的值:

〜\ App_Config \ Include \ Search Indexes \ Website.config

    ...   ...        

〜\ LIB \搜索\索引\ CustomCrawler.cs:

 using Lucene.Net.Documents; using Sitecore.Search.Crawlers; using Sitecore.Data.Items; namespace MyProject.Lib.Search.Indexing { public class CustomCrawler : DatabaseCrawler { ///  /// Determines if the item should be included in the index. ///  ///  ///  protected override bool IsMatch(Item item) { if (item["include in search results"] != "1") { return false; } return base.IsMatch(item); } } } 

有趣的是,如果我使用Index Viewer应用程序重建索引,一切都表现正常。 未选中“包含在搜索结果中”复选框的项目不会包含在搜索索引中。

但是,当我在Sitecore控制面板应用程序中使用搜索索引重建程序或当IndexingManager自动更新搜索索引时,所有项目都包括在内,无论其“包括在搜索结果中”复选框的状态如何。

我还在自定义爬虫类中设置了许多断点,当我使用内置索引器重建搜索索引时,应用程序永远不会遇到任何断点。 当我使用索引查看器时,它确实击中了我设置的所有断点。

如何让Sitecore的内置索引流程尊重我的“包含在搜索结果中”复选框?

我昨天和Alex Shyba谈过,我们能够弄清楚发生了什么。 我的配置存在一些问题,导致一切无法正常工作:

  • 正如Seth所说,Sitecore中有两个不同的搜索API。 我的配置文件正在使用它们。 要使用更新的API, 需要设置sitecore/search/configuration部分(除了我在OP中发布的内容之外,我还在sitecore/indexessitecore/databases/database/indexes ,这是不正确)。

  • 而不是重写IsMatch() ,我应该重写AddItem() 。 由于Lucene的工作方式,您无法就地更新文档; 相反,您必须先删除它,然后添加更新的版本。

    Sitecore.Search.Crawlers.DatabaseCrawler.UpdateItem()运行时,它会检查IsMatch()以查看它是否应删除并重新添加该项。 如果IsMatch()返回false,则不会从索引中删除该项, 即使它不应该首先存在

    通过重写AddItem() ,我能够指示爬虫是否应该在已删除现有文档后将该项添加到索引中。 以下是更新后的类:

    〜\ LIB \搜索\索引\ CustomCrawler.cs:

     using Sitecore.Data.Items; using Sitecore.Search; using Sitecore.Search.Crawlers; namespace MyProject.Lib.Search.Indexing { public class CustomCrawler : DatabaseCrawler { protected override void AddItem(Item item, IndexUpdateContext context) { if (item["include in search results"] == "1") { base.AddItem(item, context); } } } } 

Alex还指出我的一些可扩展性设置不正确。 特别:

  • InstanceName设置为空,这可能会导致计算机名称可能在执行之间发生更改的临时(云)实例出现问题。 我们在每个实例上更改此设置以具有恒定且不同的值(例如, CMSCD )。

  • Indexing.ServerSpecificProperties设置必须为true以便每个实例维护自己上次更新其搜索索引的记录。

  • EnableEventQueues设置必须为true才能防止搜索索引和缓存刷新进程之间的竞争条件。

  • 在开发中, Indexing.UpdateInterval应设置为相对较小的值(例如, 00:00:1500:00:1500:00:15 )。 这对于生产环境来说并不是很好,但它可以减少在排查搜索索引问题时必须要做的等待时间。

  • 确保为每个Web数据库打开历史引擎,包括远程发布目标:

         30.00:00:00   false  

要在CD实例上手动重建搜索索引,由于无法访问Sitecore后端,我还安装了RebuildDatabaseCrawlers.aspx (来自本文 )。

我想我已经找到了一个中途解决方案。

以下是Sitecore.Shell.Applications.Search.RebuildSearchIndex.RebuildSearchIndexForm.Builder.Build()的一个有趣片段,它由控制面板应用程序中的搜索索引重建器调用:

 for (int i = 0; i < database.Indexes.Count; i++) { database.Indexes[i].Rebuild(database); ... } 

database.Indexes包含一组Sitecore.Data.Indexing.Index ,它不使用数据库爬虫来重建索引!

换句话说,内置搜索索引器在重建完全忽略web.config的搜索配置设置的搜索索引时使用完全不同的类。

为解决此问题,我更改了以下文件:〜\ App_Config \ Include \ Search Indexes \ Website.config:

   ...  ...  

〜\ LIB \搜索\索引\ CustomIndex.cs:

 using Sitecore.Data; using Sitecore.Data.Indexing; using Sitecore.Diagnostics; namespace MyProject.Lib.Search.Indexing { public class CustomIndex : Index { public CustomIndex(string name) : base(name) { } public override void Rebuild(Database database) { Sitecore.Search.Index index = Sitecore.Search.SearchManager.GetIndex(Name); if (index != null) { index.Rebuild(); } } } } 

这种方法唯一需要注意的是,它将为每个数据库重建索引,而不仅仅是所选数据库(我猜测这就是为什么Sitecore有两个完全独立的方法来重建索引)。

Sitecore 6.2使用旧的和新的搜索API,因此我相信索引的构建方式不同。 CMS 6.5(即将发布)只使用较新的api – 例如,Sitecore.Search