1

首先,我只想说我对 JSR-170 和 Jackrabbit/Lucene 很陌生。

我有以下 XPath 查询:

//*[@sling:resourceType="users/user-profile" and jcr:contains(*/*/*,'sophie\-a')] order by @jcr:score descending

我有一个名为 Sophie-Allen 的用户和一个名为 Sophie-Anne 的用户。使用上述查询搜索返回零结果,其中单独搜索“sophie”返回两个用户。我知道连字符在 JSR-170 中意味着排除,但我已经逃脱了它(如您在上面看到的)。

为什么这个查询没有返回两个用户?

另一个奇怪的事情是当我使用星号时(连字符在执行时都被转义了):

  • 搜索'sophie-allen'返回 Sophie-Allen 的记录。
  • 搜索'soph*'返回 Sophie-Allen 和 Sophie-Anne。
  • 搜索'sophie-a*什么也不返回。
  • 搜索'sophie-allen*'什么也不返回。

我知道使用 jcr:contains,从技术上讲,您不需要使用星号,但看看上述行为,它似乎有某种效果。

关于 XPath 查询和搜索 JCR 中的连字符和星号,我还有什么遗漏吗?我已经搜索了我能想到的所有内容并通读了规范,但似乎找不到任何可以回答我问题的内容。

提前致谢。

编辑: 看起来“短语查询”不适用于 jcr:contains(不再?),因为默认的 Lucene 分析器在连字符上标记,这意味着它将“sophie-allen”拆分为 sophie 和 allen。

编辑 2: 我尝试使用 Jackrabbit 用户列表中某人建议的自定义分析器和标记器,但这也没有帮助,Lucene 仍在使用连字符并省略我想要的结果。

4

2 回答 2

2

您是正确的,Lucene 确实将“sophie-allen”拆分为两个标记,但这些标记是相邻的。你说你试过这样的短语表达:

... jcr:contains(*/*/*,'"sophie-a*"') ...

这应该通过找到标记“sophie”后跟另一个包含“a”作为第一个字符的标记来工作。因为应该使用在索引期间使用的相同分析器来标记这个短语表达式,所以“-”字符仍将用作分隔符 [1]。(请注意,如果您在 Java 代码中指定 XPath 表达式,则必须使用前面的反斜杠转义双引号字符。)

但是,如果这不起作用,您可以尝试去掉此表达式中的连字符。因为您使用的是通配符,所以逻辑可能错误地标记了通配符表达式。换句话说,尝试:

... jcr:contains(*/*/*,'"sophie a*"') ...

当然,如果没有通配符,这可能会起作用(有或没有连字符):

... jcr:contains(*/*/*,'"sophie-allen"') ...

祝你好运!

PS 我还没有验证这在 Jackrabbit 中是否有效,但在 ModeShape(也使用 Lucene)中确实有效。

[1] 确切的规则取决于分词器。例如,StandardTokenizer 过滤掉英语停用词,但对“-”字符进行标记,除非标记中有数字(在这种情况下,整个标记被解释为产品而不是拆分。

于 2010-08-26T13:58:51.080 回答
1

在与一位同事一起工作时,我们发现了这个用于 ModeShape 的JIRA ,偶然地由 Randall 记录(他也在这里回答了)。事实证明,问题是由于 jackrabbit 没有正确/太好地处理带有通配符的搜索词中的通配符。

Randall 已经对 ModeShape 进行了修复,但我的同事和项目团队建议在这个阶段不要修复我们的问题,因为 Jackrabbit 的使用并不是 100% 确定的。

我想将这个问题的答案与 Randall 联系起来,但他的帖子并不是真正的答案。我会将这篇文章标记为答案,除非 Randall 出现并发布一些内容。

于 2010-11-24T23:18:55.463 回答