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

7 c# config sitecore

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

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

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

<search>
  <configuration type="Sitecore.Search.SearchConfiguration, Sitecore.Kernel" singleInstance="true">
    <indexes hint="list:AddIndex">
      <index id="website" singleInstance="true" type="Sitecore.Search.Index, Sitecore.Kernel">
        ...

        <locations hint="list:AddCrawler">
          <master type="MyProject.Lib.Search.Indexing.CustomCrawler, MyProject">
            ...
          </master>

          <!-- Similar entry for web database. -->
        </locations>
      </index>
    </indexes>
  </configuration>
</search>
Run Code Online (Sandbox Code Playgroud)

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

using Lucene.Net.Documents;
using Sitecore.Search.Crawlers;
using Sitecore.Data.Items;

namespace MyProject.Lib.Search.Indexing
{
  public class CustomCrawler : DatabaseCrawler
  {
    /// <summary>
    ///   Determines if the item should be included in the index.
    /// </summary>
    /// <param name="item"></param>
    /// <returns></returns>
    protected override bool IsMatch(Item item)
    {
      if (item["include in search results"] != "1")
      {
        return false;
      }

      return base.IsMatch(item);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

小智 4

昨天我与 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\Search\Indexing\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);
          }
        }
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)

Alex 还指出我的一些可扩展性设置不正确。具体来说:

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

  • Indexing.ServerSpecificProperties设置需要使true每个实例都维护自己上次更新搜索索引的时间记录。

  • EnableEventQueues设置需要true防止搜索索引和缓存刷新进程之间的竞争条件。

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

  • 确保每个 Web 数据库(包括远程发布目标)的历史记录引擎已打开:

    <database id="production">
      <Engines.HistoryEngine.Storage>
        <obj type="Sitecore.Data.$(database).$(database)HistoryStorage, Sitecore.Kernel">
          <param connectionStringName="$(id)" />
          <EntryLifeTime>30.00:00:00</EntryLifeTime>
        </obj>
      </Engines.HistoryEngine.Storage>
      <Engines.HistoryEngine.SaveDotNetCallStack>false</Engines.HistoryEngine.SaveDotNetCallStack>
    </database>
    
    Run Code Online (Sandbox Code Playgroud)

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