lucene 正则表达式使用无连字符查询匹配带连字符单词

m3eecexj  于 2022-11-07  发布在  Lucene
关注(0)|答案(3)|浏览(213)

我设置了一个Azure存储表,其中包含很多值,这些值包含连字符、撇号和Azure索引器不喜欢的其他标点符号位。Hyphenated-Word在索引时被分解为两个标记-HyphenatedWord。因此,这意味着搜索HyphenatedWord不会产生任何结果。也就是说,Azure认知搜索拥有对Regex Lucene查询的支持。
因此,我试图找出是否有一个正则表达式模式,我可以使用它来匹配给定查询中带或不带连字符的单词。例如,查询homework应该匹配结果homework * 和 * home-work
我知道,如果我试图做相反的事情--即使在查询中提供了连字符,也要匹配不带连字符的单词--我会使用类似/home(-)?work/的东西。但是,我不确定相反的东西是什么--如果存在这样的东西的话。
有没有一个原始的正则表达式模式可以执行我所建议的那种匹配?或者我是SOL?

Edit:我应该指出,我提供的例子是不现实的,因为我并不总是知道连字符 * 应该在哪里。最理想的情况是,执行这种匹配的模式对连字符的精确位置是不可知的。
编辑2:我发现的一个解决方案 * 有效 *,但并不完全是 * 最佳 *(虽然我没有办法证明这一点,但很可能不是 performant)就是分解查询,删除所有导致标记中断的特殊字符,然后动态构建一个正则表达式查询,在查询中的每个字符之间都有一个可选的匹配。这个模式看起来像[-'\.! ]?h[-'\.! ]?o[-'\.! ]?m[-'\.! ]?e[-'\.! ]?w[-'\.! ]?o[-'\.! ]?r[-'\.! ]?k[-'\.! ]?......这也许是我见过的最丑的东西。

xxslljrj

xxslljrj1#

我对这种情况的解决方案总是引入内容和查询处理。
当您通过SDK使用推送模型时,内容处理会更容易,但是您可以通过创建表的卷影/副本来实现相同的目的,在该卷影/副本中,内容被处理以用于索引目的。您可以让原始表保持不变。然后维护一个复制表,在该复制表中处理您的文本。
无论如何,您都应该使用查询处理。在最简单的形式中,您希望在将最终用户的输入用于查询之前清除这些输入。其他步骤可以是处理连字符等特殊字符。可以对它进行转义、删除或其他操作,具体取决于您的要求。

示例

我必须支持对可能包含连字符或其他特殊字符的订购代码的搜索。我们订购代码的维护者可能会以不一致的格式定义订购代码。访问我们网站的客户也一样不一致。
要求ABC-123-DE_F-4.56G应与以下任一项匹配

  • ABC-123-DE_F-4.56G型自动变速器
  • ABC123-德国-F-4.56G
  • 第123页
  • ABC.123.DE.F.4.56G
  • ABC品牌123 DEF 56 G
  • ABC123 DEF 56 G系列

我使用上面建议的方法来解决这个问题。我使用内容处理来生成一个没有任何特殊字符的订购代码版本(使用一个简单的正则表达式)。然后,我使用查询处理来将最终用户的输入转换为OR查询,例如:

<verbatim-user-input-cleaned> OR OrderCodeVariation:<verbatim-user-input-without-special-chars>

因此,如果用户输入ABC.123.DE.F.4.56G,我将有效地搜索

ABC.123.DE.F.4.56G OR OrderingCodeVariation:ABC123DEF56G
j0pj023g

j0pj023g2#

听起来你想定义自己的标记化。使用自定义标记化器会有帮助吗?https://learn.microsoft.com/azure/search/index-add-custom-analyzers

k0pti3hp

k0pti3hp3#

为了补充Jennifer的答案,您可以考虑使用一个自定义分析器,该分析器由以下令牌过滤器之一组成:

  • pattern_replace:一个标记筛选器,它将模式应用于流中的每个标记,用指定的替换字符串替换匹配项。
  • pattern_capture:使用Java正则表达式发出多个标记,一个标记对应于一个或多个模式中的每个捕获组。

您可以使用 pattern_replace 标记过滤器将连字符替换为所需的字符(可能是空字符)。

相关问题