首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在JCR 2中包含查找不相等的文本字符串?

为什么在JCR 2中包含查找不相等的文本字符串?
EN

Stack Overflow用户
提问于 2018-01-03 12:37:21
回答 2查看 4.5K关注 0票数 5

在使用JCR-SQL2查询时,我注意到CONTAINS操作符查找的节点不具有与条件完全相同的字符串。

示例

以下查询:

代码语言:javascript
复制
SELECT * FROM [nt:base] AS s WHERE CONTAINS(s.*, 'my/search-expression')

不会只找到包含my/search-expression字符串的节点,也不会找到具有字符串(如my/another/search/expression )的节点。

为什么查询没有找到所提供的确切字符串?如何才能改变它以缩小结果?

为了分享知识,这个问题是由我来回答的--但是可以自由地添加你自己的答案,或者改进一个现有的答案。

EN

回答 2

Stack Overflow用户

发布于 2018-01-03 12:37:21

示例查询的执行计划揭示了问题的根源:

代码语言:javascript
复制
  [nt:base] as [s] /* lucene:lucene(/oak:index/lucene) +:fulltext:my +:fulltext:search +:fulltext:expression ft:("my/search-expression") where contains([s].[*], 'my/search-expression') */

CONTAINS运算符触发全文搜索。非单词字符,如"/“或"-",用作单词分隔符。因此,查询将查找所有包含单词"my“、"search”和“表达式”的节点。

它能做些什么?有几种选择。

1.使用双引号

如果您希望将结果限制在具有给定单词的短语中,并且在它们之间没有任何其他单词,请将搜索表达式放在双引号中:

代码语言:javascript
复制
SELECT * FROM [nt:base] AS s WHERE CONTAINS(s.*, '"my/search-expression"')

现在,执行计划是不同的:

代码语言:javascript
复制
[nt:base] as [s] /* lucene:lucene(/oak:index/lucene) :fulltext:"my search expression" ft:("my/search-expression") where contains([s].[*], '"my/search-expression"') */

现在,查询将查找整个短语,而不是单个单词。然而,它仍然忽略非单词字符,因此也会找到这样的短语:“我的搜索表达式”或“我的搜索表达式”。

2.使用类似的表达式(不建议使用)

如果只想找到保留非单词字符的确切短语,可以使用LIKE表达式:

代码语言:javascript
复制
SELECT * FROM [nt:base] AS s WHERE s.* LIKE '%my/search-expression%'

然而,这是慢得多的。在解释执行计划时,我需要添加另一个条件以避免超时。对于此查询:

代码语言:javascript
复制
SELECT * FROM [nt:base] AS s WHERE s.* LIKE '%my/search-expression%'  AND ISDESCENDANTNODE([/content/my/content]) 

执行计划是:

代码语言:javascript
复制
[nt:base] as [s] /* traverse "/content/my/content//*" where ([s].[*] like '%my/search-expression%') and (isdescendantnode([s], [/content/my/content])) */

它只会找到带有以下短语的节点:“my/search-表达式”。

3.使用双引号并改进结果

最好是使用第一种方法(带有双引号的CONTAINS),并在以后细化结果,例如,在应用程序代码中,如果查询是从应用程序运行的。

4.混合含有和类似物

另一种选择是将全文搜索和LIKE表达式与AND混合使用。

代码语言:javascript
复制
SELECT * FROM [nt:base] AS s WHERE CONTAINS(s.*, '"my/search-expression"') AND s.* LIKE '%my/search-expression%'

现在的执行计划是:

代码语言:javascript
复制
[nt:base] as [s] /* lucene:lucene(/oak:index/lucene) :fulltext:"my search expression" ft:("my/search-expression") where (contains([s].[*], '"my/search-expression"')) and ([s].[*] like '%my/search-expression%') */

现在,它应该是快速和严格的同时。

票数 7
EN

Stack Overflow用户

发布于 2020-09-08 10:54:07

也有同样的问题。

因此,基本上您应该为lucene索引定义不同的标记器,在我的例子中,“空格”标记器很好。

使用标准标记器,“my/search-表达式”被拆分为3个标记"my“、"search”、“表达式”。标准标志符使用一些特殊字符作为分隔符。

这就是为什么“我/搜索-表达式”得到0的原因。

另一个例子是:

“一些-其他我的搜索/表达式”,与空格标记器,这是分裂成:

“一些-其他”、“我的”、“搜索/表达”

当您搜索“一些-其他我的”,这应该会返回结果。

标记器列表

Lucene索引示例:

代码语言:javascript
复制
<yourLucene
jcr:primaryType="oak:QueryIndexDefinition"
type="lucene"
async="async"
evaluatePathRestrictions="{Boolean}true"
includedPaths="[/somepath]"
queryPaths="[/somepath]"
compatVersion="{Long}2">
<analyzers jcr:primaryType="nt:unstructured">
    <default jcr:primaryType="nt:unstructured">
        <tokenizer
            jcr:primaryType="nt:unstructured"
            name="Whitespace"/>
        <filters jcr:primaryType="nt:unstructured">
            <Standard jcr:primaryType="nt:unstructured"/>
            <LowerCase jcr:primaryType="nt:unstructured"/>
            <Stop jcr:primaryType="nt:unstructured"/>
        </filters>
    </default>
</analyzers>
<indexRules jcr:primaryType="nt:unstructured">
    <nt:unstructured jcr:primaryType="nt:unstructured">
        <properties jcr:primaryType="nt:unstructured">
            <someprop
                jcr:primaryType="nt:unstructured"
                name="someprop"
                propertyIndex="{Boolean}true"
                type="String"/>
        </properties>
    </nt:unstructured>
</indexRules>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48077571

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档