从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/indexes
和sitecore/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
设置为空,这可能会导致计算机名称可能在执行之间发生更改的临时(云)实例出现问题。 我们在每个实例上更改此设置以具有恒定且不同的值(例如,CMS
和CD
)。 -
Indexing.ServerSpecificProperties
设置必须为true
以便每个实例维护自己上次更新其搜索索引的记录。 -
EnableEventQueues
设置必须为true
才能防止搜索索引和缓存刷新进程之间的竞争条件。 -
在开发中,
Indexing.UpdateInterval
应设置为相对较小的值(例如,00:00:15
:00:00:15
:00: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