如何在过滤条件下使用cts:values / cts:element-attribute-values

时间:2018-12-06 12:46:19

标签: xquery marklogic

我有以下两个文档,并且分别在数据类型为string,string,string和integer的元素“ Id”,“ Name”,“ Key”和“ Value”上创建了范围索引。

<Root Id='1'>
 <Name>ABC</Name>
 <Child>
  <Key>1</Key>
  <Value>10</Value>
 </Child>
 <Child>
  <Key>2</Key>
  <Value>20</Value>
 </Child>
</Root>

<Root Id='2'>
 <Name>ABC</Name>
 <Child>
  <Key>1</Key>
  <Value>20</Value>
 </Child>
 <Child>
  <Key>2</Key>
  <Value>10</Value>
 </Child>
</Root>

以下查询应返回文档1,但相反,它返回两个文档,因为cts:element-attribute-values返回基于“未过滤”的结果。

cts:element-attribute-values(xs:QName("Root"),xs:QName("Id"), (), (),
cts:and-query((
    cts:element-value-query(xs:QName("Name"), "ABC"),
    cts:element-query(xs:QName("Child"),
        cts:and-query((
            cts:element-value-query(xs:QName("Key"), "1"),
            cts:element-range-query(xs:QName("Value"), "<", 15)
        ))
    )
))
)

有没有一种方法可以基于过滤获得结果。

注意:我不想使用cts:search(),因为我的查询将返回超过100,000条记录

2 个答案:

答案 0 :(得分:4)

当然,最佳实践是每个“行”有一个文档,但是您也可以使用位置来解决此问题:如果您在同一个cts:element-query中有两个值查询,并且您有单词位置和范围位置启用后,索引可以使用位置来解决此问题。

答案 1 :(得分:0)

cts:element-attribute-values的{​​{1}}文档说:

  

仅在cts:query选择的片段中包含值,并从这组包含的值中计算频率。 值不需要与查询匹配,但是它们必须出现在查询选择的片段中。不对片段进行过滤以确保它们与查询匹配,而是以与“未过滤的” cts:search操作相同的方式进行选择。如果输入字符串,则将该字符串视为指定字符串的cts:word-query。

正如您已经注意到的那样,查询过滤器无法返回到假阳性,因此无法不进行过滤。 $query也没有过滤的选项。

您可以尝试执行以下操作:

cts:element-attribute-values创建一个片段根。这样一来,您的查询可以不经过滤就运行,而不会返回假阳性。

Child

我在这里所做的解释:

通过在cts:element-attribute-values(xs:QName("Root"),xs:QName("Id"), (), (), cts:and-query(( cts:element-value-query(xs:QName("Name"), "ABC"), cts:document-fragment-query( cts:element-query(xs:QName("Child"), cts:and-query(( cts:element-value-query(xs:QName("Key"), "1"), cts:element-range-query(xs:QName("Value"), "<", 15) )) ) ) )) ) 上创建片段根,每个子级都保存在自己的片段中。这样,在ChildKey上的and-query只会返回实际上包含给定值的片段。通过创建Value,您将检查文档是否包含其中一个片段(这是必需的,因为跨片段搜索无效)。

希望这会有所帮助。