我有一个包含数万个的marklogic(4.2)数据库 大型,复杂的(有些较小,但大的是10MB +) 正在以编程方式使用相当复杂的文档进行搜索的文档 构建搜索:搜索电话。在正常使用中,返回一些结果 时间使用分页,并生成匹配的片段,它的工作原理 精细。现在,其中一个客户端开发人员需要返回 all 即使在他构建了一个查询的情况下,也可以立即从该查询得到结果 返回DB中所有文档的查询。他最不在乎 但是比赛的内容;只有几个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
真慢
答案 0 :(得分:1)
您可以尝试一些方法:流式搜索结果,共现事件和编码词典值。
您已经触及了编码的词典值,我认为这将是最有效的方法。它可能感觉像是一个黑客,但它是基于函数的索引的道德等价物。它应该很好地扩展。
同样使用范围索引和词典函数将是cts:element-value-co-occurrences
。这不会像编码值那样扩展,但预先做的工作较少。请务必考虑“地图”选项:http://docs.marklogic.com/cts:element-value-co-occurrences
最后,你可以简单地给开发者提供他想要的东西。使用search:parse
正常解析查询,或使用cts:query
构造函数构建查询。然后调用cts:search
以获取匹配的节点并返回它们。结果会很大,但这是不可避免的。您可能会遇到XDMP-EXPNTREECACHEFULL
错误:请查看http://blakeley.com/blogofile/2012/03/19/let-free-style-and-streaming/以了解这些错误。它可能需要在两侧进行一些棘手的编码,但这可以让你返回任意大的结果序列。