我有一个 marklogic (4.2) 数据库,其中包含数以万计的大型、复杂(有些较小,但大的是 10MB+)文档,这些文档正在使用相当复杂的、以编程方式构建的 search:search 调用进行搜索. 在正常使用中,使用分页一次返回几个结果,并生成匹配的片段,它工作正常。现在,其中一位客户端开发人员需要一次返回该查询的所有结果,即使在他构建了一个返回数据库中所有文档的查询的情况下也是如此。不过,他并不关心比赛的大部分内容。只有几个 ID 元素(一个数字和一个自由文本),它们都被索引,并且它们总是在文档中的相同 xpath 中。
问题是,我无法想出一种有效的方法来查询这么大的数据集中的两个元素。它总是需要加载整个文档,而查询只是在长草中消失了几万次,并且基本上永远不会返回。
我尝试在其中一个元素上使用元素值词典,并通过搜索过滤。这很快就会返回,但有几个缺点: * 它返回误报。这不一定会破坏交易,但不是最理想的。* 它只获取其中一个元素;一旦我尝试迭代该列表并获取他感兴趣的另一个元素,不出所料地需要永远(因为我们要为每次匹配加载整个文档。)
我想知道是否声明一个包含这两个元素的字段可能会有所帮助(我可以使用词典来获取其中一个值,然后在该字段中查找它,而不是加载整个文档来获取一个 ID,)但我以前从未使用过字段,而且看起来它们总是单词查询,而不是元素查询,这对于我需要用它们做的事情来说听起来并不理想。
我还认为可能在文档中创建一个新元素,其中包含两个 ID 的编码形式,这将允许我创建一个包含两者的索引,然后使用我上面提到的词典方法将其缩小到至少匹配的文档未过滤的搜索。不过,这感觉像是一种非常老套的方法。
我真正在寻找的是一种方式来表达“这是一个搜索,这里是我感兴趣的(索引)元素,现在获取它们的值以匹配文档”。有没有办法做到这一点?
我觉得答案是“不”,但值得一问。
如果没有,是否有人对哪些替代方法可能最有效提出建议?
谢谢。
文档格式示例:
<doc:entity>
<doc:metadata>
<doc:sap-metadata>
<doc:info>
<doc:id>12345678</doc:id>
<doc:number>AS-1990 13:45</doc:number>
<!-- more document info here -->
</doc:info>
</doc:sap-metadata>
</doc:metadata>
<doc:content>
<!-- a lot of text content here... -->
</doc:content>
</doc:entity>
搜索代码(初剪):
搜索代码一点也不聪明。只是一个标准的搜索:带有搜索词的搜索调用和(至少一个约束 - 为了清楚起见,我坚持简单的情况):
search:search(fn:concat("relevant:1 ", $search-term), $search-options)
$search-term
是用户提供的明文搜索。$search-options
是相当多的xml,但我不认为包含任何异国情调;只是一堆约束和方面定义和自定义片段,由以下生成:
declare function func:do-snippet(
$result as node(),
$ctsquery as schema-element(cts:query),
$options as element(search:transform-results)?
) as element(search:snippet)
{
element search:snippet{
element search:match {
fn:doc(xdmp:node-uri($result))/doc:entity/doc:metadata/doc:sap-metadata/doc:info/doc:id,
fn:doc(xdmp:node-uri($result))/doc:entity/doc:metadata/doc:sap-metadata/doc:info/doc:number
}
}
};
搜索代码(第二切):
这个是使用 id 上的 element-value-lexicon 生成与搜索词匹配的 ID 列表(显然未过滤),然后使用该 id 查询文档编号:
let $query := ...
let $options := ...
for $id in cts:element-values(fn:QName("http://my.document.namespace", "id"), (), (), cts:query(search:parse($query, $options)))
return element document {
attribute id {$id},
attribute number {
cts:element-values(fn:QName("http://my.document/namespace", "number"), (), (), cts:element-value-query(fn:QName("http://my.document.namespace", "id"), $id ))
}}
第一个cts:element-values
调用返回很好而且很快,但是迭代响应并cts:element-values
为每个响应做另一个真的很慢。