【问题标题】:Sitecore Lucene index search term with space match same word without space带空格的 Sitecore Lucene 索引搜索词匹配不带空格的相同词
【发布时间】:2016-08-17 16:30:00
【问题描述】:

这看起来很简单,以至于我确信我一定忽略了一些东西。我无法确定如何在 Lucene 中执行以下操作:

问题

  • 我正在搜索地名。
  • 我有一个名为Name 的字段
  • 它正在使用Lucene.Net.Analysis.Standard.StandardAnalyzer
  • TOKENIZED
  • Name 的值中包含 1 个空格:halong bay
  • 由于文化上不同的拼写或真正的拼写错误,搜索词可能包含也可能不包含额外的空格。例如。 ha long bay 而不是 halong bay
  • 如果我使用术语 halong bay,我会大获成功。
  • 如果我使用 ha long bay 这个词,我不会受到打击。

尝试的解决方案

这是我使用 LINQ to Lucene 从 Sitecore 构建我的谓词的代码:

var searchContext = ContentSearchManager.GetIndex("my_index").CreateSearchContext();
var term = "ha long bay";
var predicate = PredicateBuilder.Create<MySearchResultItemClass>(sri => sri.Name == term);
var results = searchContext.GetQueryable<MySearchResultItemClass>().Where(predicate);

我还尝试了使用 .Like() 扩展的模糊匹配:

var predicate = PredicateBuilder.Create<MySearchResultItemClass>(sri => sri.Like(term));

这也不会为ha long bay 产生任何结果。

如何在 Sitecore 中配置 Lucene 以返回对 halong bayha long bay 搜索词的匹配,理想情况下无需对输入词做任何花哨的操作(例如,剥离空间、添加通配符等)?

注意:我知道这也可以让 h a l o n g b a y 一词产生成功,但我认为我对此没有问题。

【问题讨论】:

  • 对于拼写错误的短语,通常使用同义词而不是让您的搜索逻辑涵盖所有基础。查看这篇关于使用 Sitecore 进行设置的帖子。如果您有更多此类场景,可能值得考虑 - firebreaksice.com/sitecore-synonym-search-with-lucene
  • 感谢您对同义词的提醒。我实际上可能会为其他类型的搜索实现它。但是,在我看来,这不是同义词。这是同一个词,但添加了空格。也许我很迂腐,但使用同义词的原因是要指定完全不同的单词,即使它们具有相同的含义,它们在数学上也没有任何共同点,例如“快速”和“快速”的常用字母为零。

标签: c# linq lucene sitecore


【解决方案1】:

TOKENIZED 字段表示字段值被标记(在这种情况下为空格)分割,结果项被添加到索引字典中。如果您在这样的字段中索引“halong bay”,它将创建“halong”和“bay”术语。

搜索引擎无法为“ha long”搜索查询检索到此结果是正常的,因为它不知道任何带有“ha”或“long”字词的结果。

手动方法是定义在另一个名为 AlternateNames 的多值计算索引字段中写入地名的所有其他方法。然后你可以发出这种查询:Name==query OR AlternateNames==query

一种自动方法是在名为 CompactName 的单独计算索引字段中也索引不带空格的地名。然后你可以发出这种查询:Name==query OR CompactName==compactedQueryWithoutSpaces

希望对你有帮助

杰夫

【讨论】:

  • 感谢您的回答。我想知道将其更改为未标记化是否允许在不操纵输入项的情况下进行匹配?我试图不必为了考虑空格而编写单独的替代名称列表。
【解决方案2】:

这样的事情可能会奏效:

var predicate = PredicateBuilder.False<MySearchResultItemClass>();
foreach (var t in term.Split(' '))
{
    var tempTerm = t;
    predicate = predicate.Or(p => p.Name.Contains(tempTerm));
}
var results = searchContext.GetQueryable<MySearchResultItemClass>().Where(predicate);

它确实拆分了您的输入字符串,但我猜这不是“花式”;)

【讨论】:

  • 我担心这会匹配任何带有单词“bay”或“ha”或“long”的东西,这不是我想要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多