Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
CTS和xPath都是必需的吗?_Xpath_Xquery_Marklogic - Fatal编程技术网

CTS和xPath都是必需的吗?

CTS和xPath都是必需的吗?,xpath,xquery,marklogic,Xpath,Xquery,Marklogic,我有以下CTS搜索查询: cts:search(/parent, cts:and-query(( cts:element-attribute-value-query(xs:QName('parent'), xs:QName('attr'), 'value'), cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-1'), 'value-2'), cts:e

我有以下CTS搜索查询:

cts:search(/parent, 
    cts:and-query((
        cts:element-attribute-value-query(xs:QName('parent'), xs:QName('attr'), 'value'),
        cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-1'), 'value-2'),
        cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-2'), 'value-3')
    ))
)/child[@attr-1 eq 'value-2' and @attr-2 eq "value-3"]

(: Returns /parent/child elements matching criteria :)
我有一些关于父母的限定词,也有关于孩子的限定词。但我想要的最终结果只是孩子们。要做到这一点,正如你从上面看到的,我必须:

  • 搜索符合父条件+子条件的文档
  • 获取该文档后,按照与上面相同的条件逻辑筛选出子项
这是可行的,但我必须在cts:query中使用与在xPath中为子对象使用相同的逻辑,这似乎真的很愚蠢。逻辑被不必要地重复了

是否有一种方法可以在cts:query中完成这一切,而不必像上面的示例那样使用额外的xPath表达式?


这与我想要的类似,但不适用于注释中指定的问题:

cts:search(/parent/child, 
    cts:and-query((
        cts:element-attribute-value-query(xs:QName('parent'), xs:QName('attr'), 'value'), (: The problem is this line... I can't filter by the parent, as it is above the scope of my first parameter (/parent/rule) :)
        cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-1'), 'value-2'),
        cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-2'), 'value-3')
    ))
)

您仍然可以查询父级,即使您的搜索跨越了子级:

cts:search(/parent/child, 
    cts:and-query((
        cts:element-attribute-value-query(xs:QName('parent'), xs:QName('attr'), 'value'),
        cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-1'), 'value-2'),
        cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-2'), 'value-3')
    ))
)
这将作为过滤搜索运行,但由于您一直在手动执行过滤,因此性能应该大致相当

更新:

我对此进行了测试,上面的断言是错误的。我认为这是对的,但显然
cts:search
过滤将过滤与可搜索表达式不完全匹配的结果。父项将超出可搜索表达式的范围

理想情况下,您可以在
子元素上分解文档,但至少可以删除重叠的查询和XPath,如下所示:

cts:search(/parent/child, 
    cts:and-query((
        cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-1'), 'value-2'),
        cts:element-attribute-value-query(xs:QName('child'), xs:QName('attr-2'), 'value-3')
    ))
)[parent::parent/@attr = 'value']

wst给了你答案。然而,这一切都来自于需要过滤。在MarkLogic中,一个文档应该反映一个“记录”。是否可以重构文档以避免首先进行筛选?

这对我不起作用。当我使用
/parent
作为可搜索表达式时,我将从cts:search返回父表达式。当我输入
/parent/child
作为可搜索表达式时,我没有得到任何返回。cts:查询本身从未改变,我所改变的只是可搜索的表达式。当我有
/parent/child
时,它不起作用。我的假设是,父元素上的第一个元素属性值查询会抛出所有内容,因为它不在可搜索表达式(?)之下,感谢您的wst更新。您还可以轻松地反转逻辑,从cts:search中获取父级,然后使用xPath筛选子级。在我的例子中,你过滤孩子的地方实际上会更快,因为它比父母更具体。我仍然希望(根据问题)在cts中解决所有这些问题:寻找纯粹的风格原因,但这可能是不可能的。计算成本是否与过滤cts:search的计算成本相同,因为它是通过xPath表达式过滤的?@CtheGood计算,让cts:search尽可能多地完成繁重的工作是最好的策略。它可以返回的所有未经过滤的结果将仅使用索引进行解析,因此它们将非常快。如果您必须通过cts:search或通过XPath手动使用筛选,那么数据库必须1)选择更多的文档,2)将它们加载到内存中以执行筛选。对于如何最大化前者和最小化后者,没有通用的规则——这取决于您的文档,所以测试不同的方法几乎是您所能做的。不,不是这样。我的文档已经非常简单了,每个文档都有根元素,只有1个深层子元素(ie)。父对象和所有子对象都有属性。我只想得到已经是目标家长的几个目标孩子。我总是需要使用双逻辑-cts:在父级上搜索,然后使用xPath按照相同的逻辑进行过滤。但是,我想用关系类比来巩固David的建议,在MarkLogic中,最好将文档视为行,而不是表。为了获得理想的查询性能,您需要在需要查询的数据和单个文档之间建立一对一的关系。在您的情况下,我可能会创建一个文档(或使用片段根…,但要小心)并传播(复制)从父文档到子文档查询的任何重要数据。这种类型的“非规范化”在ML中非常常见。当然,这就是平衡。不完全是一门艺术——但一些个人选择起了作用。你也必须考虑你没有;在MarkLogic中不一定需要微小的片段,因此如果子文档是“微小的”(请参阅文档以获取指导),那么将它们打包到一定的大小并应用过滤是一个可行的选择。例如,即使是ML中的三元组(3个元素和一个父元素)在导入时也会以大约100的速度存储在片段中,而不是单独存储。