Jackrabbit XPath查询中的连字符问题

时间:2010-08-26 05:27:29

标签: lucene xpath jackrabbit jcr jsr170

首先,我要说的是,我对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 Analyzer在连字符上标记,意味着它将'sophie-allen'分割为sophie和allen。

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

2 个答案:

答案 0 :(得分:2)

你是对的,Lucene确实将“sophie-allen”分成两个代币,但这些代币是相邻的。你说过你尝试过这样的短语表达式:

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

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

但是,如果这不起作用,您可以尝试在此表达式中取出连字符。因为您正在使用通配符,所以逻辑可能会错误地将通配符表达式标记化。换句话说,尝试:

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

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

... jcr:contains(*/*/*,'"sophie-allen"') ...
祝你好运!

P.S。我没有证实这适用于Jackrabbit,但它在ModeShape(也使用Lucene)中有效。

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

答案 1 :(得分:1)

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

兰德尔已经为ModeShape做了一个修复,但我的同事和项目团队提名不要在现阶段解决我们的问题,因为使用Jackrabbit不是100%肯定。

我想将这个问题的答案与兰德尔联系起来,但他的帖子并不是真正的答案。我会把这篇文章标记为答案,除非兰德尔出现并张贴一些东西。