我正在学习如何使用 MarkLogic Optic API,到目前为止,它的灵活性给我留下了深刻的印象。但是,我无法弄清楚如何生成类似于
search.snippet
或 jsearch 的输出的搜索片段。使用 Optic API 可以吗?
谢谢!
这取决于您搜索的内容/方式以及您返回的结果。没有将光学计划(通常由许多步骤和联接组成)转换为可以针对文档运行以创建的单个查询有问题的片段。但是,如果您要将文档绑定到光学查询上,并且有某种方法来隔离您想要片段的内容,那么是的,这是可能的。考虑下面的示例。请注意,它有 2 个语句(1)插入和(2)查询。分号的位置对于查询控制台很重要。
一些注意事项:
可能有几个地方可以缝合。但是,根据最佳实践,我在分页后给出了highligting的示例。突出显示、片段和行走等都是重要功能,因此请尽可能在分页后使用,
这可以使用 op:map() 实现,因为我可以提取文档并对其进行操作。人们可能会想在 op:select 或 op:bind 中做同样的事情。然而,即使 cts:highlight 在 octs:highlight 下可用(我没有检查),我们也必须导入额外的库,并且基本上得到相同的结果。由于我只会在分页后应用此功能,因此我没有检查。然而,应用 op:map 后就无能为力了。
xquery version "1.0-ml";
(
xdmp:document-insert("/comment-1.xml",<doc><some-node><comment>Hello, I am a llama</comment></some-node></doc>),
xdmp:document-insert("/comment-2.xml",<doc><some-node><comment>Hello, I am an emu</comment></some-node></doc>)
);
(: ------------------------This is a separate statement started after the semicolon(;) avove ------------------------------------ :)
xquery version "1.0-ml";
import module namespace op="http://marklogic.com/optic"
at "/MarkLogic/optic.xqy";
let $query := cts:word-query("llama")
return op:from-search-docs($query)
=>op:offset-limit(1,10)
=>op:map(function($row){ $row=>map:with("match", cts:highlight(map:get($row, "doc"), $query, <match>{$cts:text}</match>))})
=>op:result()
结果: 原始文档:
<doc>
<some-node>
<comment>Hello, I am a llama</comment>
</some-node>
</doc>
突出显示:
<doc>
<some-node>
<comment>Hello, I am a <match>llama</match></comment>
</some-node>
</doc>
为了补充 David 的精彩答案,这里有另一种方法将
search:snippet
应用为后处理步骤:
const query = cts.wordQuery('marklogic')
op
.fromSearchDocs(query)
.limit(10)
.select([
op.as('title', op.xpath(op.col('doc'), '/article/title/text()')),
op.as('keywords', op.xpath(op.col('doc'), '/article/keywords/keyword/text()')),
op.col('doc'),
])
.result()
.toArray()
.map(({doc, ...rest}) => ({
...rest,
snippets: search.snippet(doc, query)
}))