I am learning how to use the MarkLogic Optic API and so far I am impressed by its flexibility. However, I am not able to figure out how to produce search snippets similar to output from search.snippet
or jsearch. Is it something possible using the Optic API?
Thanks!
It depends on what/how you are searching and the results you are getting back.. There is no translation of an optic plan (often built up of many steps and joins) into a single query that could be run against a document to create the snippet in question. However, if you were to bind the document onto your optic query and had some way to isolate what you want to snippet, then yes, it is possible. Consider the sample below. Note that it has 2 statements (1) insert and (2) query. The semicolon placement is important for query console.
A few notes:
Probably a few places that this could be stitched in. However following best practices, I gave an example of highligting after pagination. Highlight and snippet and walk etc are all heavy-hitting features, so use after pagination when possible,
This was possible using op:map() because I could extract the doc and manipulate it. One might be tempted to have done the same in an op:select or op:bind. However, even if cts:highlight was available under octs:highlight(I did not check), we would have had to import the additional library and essentially ended up with the same result. Since I would apply this only after pagination, I did not check. However, not much can be done after an op:map is applied.
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()
Results: Original doc:
<doc>
<some-node>
<comment>Hello, I am a llama</comment>
</some-node>
</doc>
Highlighted:
<doc>
<some-node>
<comment>Hello, I am a <match>llama</match></comment>
</some-node>
</doc>