3

我有以下查询字符串:

SELECT jcr:title, jcr:created, jcr:description FROM cq:PageContent WHERE jcr:path LIKE '/content/.../%' AND CONTAINS (., '*') ORDER BY date ASC

问题是查询正在返回给定路径中的所有节点,即使它们在任何属性中都没有星号。我想转义星号字符,但结果是一样的。我试过这样的事情:

SELECT jcr:title, jcr:created, jcr:description FROM cq:PageContent WHERE jcr:path LIKE '/content/.../%' AND CONTAINS (., '\*') ORDER BY date ASC

甚至是这样的:

SELECT jcr:title, jcr:created, jcr:description FROM cq:PageContent WHERE jcr:path LIKE '/content/.../%' AND CONTAINS (., '\*\*\*\*\*\*\*\*\*\*\*') ORDER BY date ASC

在所有这些查询中,结果是相同的,即使这些页面都没有包含星号字符的属性(或其中 11 个)

jcr:contains 函数的文档说:

在单引号 (“'”) 的 searchexp 文字实例中,双引号 (“"”) 和连字符 (“-”) 必须用反斜杠 (“\”) 转义。因此,反斜杠本身也必须转义,以结束作为双反斜杠(“\”)。

没有提到其他字符*,因此即使没有任何转义(?),它也应该可以工作。请让我理解为什么我在这里得到这样的结果以及如何正确地转义这些字符。

4

3 回答 3

2

您输入的文档有答案。您必须转义一些特殊字符,但是如果您希望诸如星号之类的文字仅匹配字符“*”,则必须使用作为反斜杠的转义字符。文档说明有点令人困惑的是反斜杠本身在解析字符串时是一个特殊字符,因此如果您希望将反斜杠视为转义字符,则需要对其进行转义。

换句话说,要转义星号,您需要将其写为

\\*
于 2018-04-07T12:37:19.497 回答
1

我不确定,如果jcr:contains是适合你的方法。也许jcr:like是你想要的更好的方法。

jcr:contains是全文搜索,并使用 lucene 索引。所以它可能会产生一些意想不到的影响。它也不能那么容易地与其他索引结合。

jcr:like是与通配符的属性比较。这个通配符可以用反斜杠转义。(https://docs.adobe.com/docs/en/spec/jcr/1.0/6.6.5.1_jcr_like_Function.html


第一个示例 SQL-2 查询

在任何属性中搜索带有 * 的 cq:PageContent 节点。%(百分号)是通配符符号。* 被搜索。

SELECT * FROM [cq:PageContent] AS content
WHERE ISDESCENDANTNODE('/content/myproject/...')
AND content.* LIKE '%*%'

第二个示例 SQL-2 查询

在任何属性中搜索带有 % 的 cq:PageContent 节点。因此百分号用 \% 转义(并被通配符 % 包围)。

SELECT * FROM [cq:PageContent] AS content
WHERE ISDESCENDANTNODE('/content/myproject/...')
AND content.* LIKE '%\%%'

第三个示例 XPath 查询

与上一个几乎相同,就像 XPath 查询一样。只有我不知道,如何搜索任何属性。所以这个例子搜索 jcr:title 属性。

/jcr:root/content/myproject/...//element(*, cq:PageContent)[jcr:like(@jcr:title, '%\%%')]
于 2018-04-12T14:04:20.467 回答
0

我终于在Jackrabbit Wiki 页面上找到了答案

在全文(包含)子句中转义文本

Jackrabbit Oak 使用Apache Lucene 语法进行全文搜索。因此,要转义用户提供的文本以在包含中使用,您需要过滤掉所有特殊字符,或者转义它们。例如,要过滤掉特殊字符,请使用:

String filteredContains = searchTerm.replaceAll("[\\Q+-&|!(){}[]^\"~*?:\\/\\E]", ""); String q = "/jcr:root/foo/element(*, foo)" + "[jcr:contains(@title, '" + filteredContains.replaceAll("'", "''") + "')]" + "[@itemID = '" + itemID.replaceAll("'", "''") + "']";

仅适用于 Jackrabbit 2.x:Text.escapeIllegalXpathSearchChars(...)用于调用 jcr:contains(...)(另请参阅 JCR-1248):

String q = "/jcr:root/foo/element(*, foo)" + "[jcr:contains(@title, '" + Text.escapeIllegalXpathSearchChars(searchTerm).replaceAll("'", "''") + "')]" + "[@itemID = '" + itemID.replaceAll("'", "''") + "']";

于 2018-04-09T09:44:09.193 回答