MarkLogic不区分大小写的片段搜索

4

目前,我正在使用这段代码生成片段,该代码基于我从MarkLogic搜索获取的JSON文档。

xquery version "1.0-ml";
module namespace searchlib="http://ihs.com/lib/searchlib";
import module namespace search="http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy"; 
import module namespace json="http://marklogic.com/xdmp/json" at "/MarkLogic/json/json.xqy";

declare function searchlib:get-snippet($docc,$words) {
  let $doc:= json:transform-from-json($docc)
  let $squery := search:parse($words)
  let $result := <result>{search:snippet($doc,$squery,
  <transform-results apply="snippet" xmlns="http://marklogic.com/appservices/search">
          <max-snippet-chars>255</max-snippet-chars>

      </transform-results>)}</result>

  return $result//search:match
};

在执行搜索时,我使用:

cts.jsonPropertyValueQuery(fieldname, values, 
                                             ['case-insensitive', 'diacritic-insensitive'])

所以搜索是不区分音符号的,并能产生良好的结果,但在search:snippet中,我无法像在cts.jsonPropertyValueQuery中那样传递diacritic-insensitive选项。
文档中,我可以看到以下描述:
引用:

定义搜索语法和控制搜索的选项。有关函数search:search的$options的说明,请参见说明。请注意,在transform-results选项上无法指定apply属性与search:snippet一起使用;要使用不同的片段化函数,请改用search:search或search:resolve。

但这里是:
search:snippet(
   $result as node(),
   $cts-query as schema-element(cts:query),
   [$options as element(search:transform-results)?]
) as element(search:snippet)

这是否意味着我不能传递其他选项给search:snippet?还是有选项可以做到这一点?
我正在使用“chávez”进行测试,它产生了结果,但只有包含精确匹配的文档才会生成正确的摘录,也就是说,文档

Chavez did something

不会在“Chavez”上高亮显示,而

Chávez did something

将高亮显示。
提前感谢!

我认为你的意思是 <search:highlight>Chavez</search:highlight> 不是结果的一部分。这很可能是 MarkLogic 的一个 bug,因为它似乎与此函数的预期相反。作为一种解决方法,您可以考虑编写一个添加高亮后处理的函数,但这样做可能并不容易(考虑使用 NFD(分解),这使得在搜索术语和结果上删除变音符号以及使用普通的 XPath/XQuery 函数在结果中搜索变得容易)。 - Abel
@Abel 是的,那正是我的问题。我没有在“Chavez”上得到高亮显示。我担心手动操作会降低性能,但也许我会尝试编写一些解析文档的函数。谢谢! - Kamil Budziewski
你也应该考虑让 MarkLogic 知道,如果这是一个 bug,也许他们已经有了解决方法,甚至是补丁。 - Abel
@Abel 我已经向MarkLogic提交了一个工单 :) - Kamil Budziewski
如果他们回答说有绕过的方法、解决方案或者“抱歉,这不是将被考虑的功能”,你能用它来回答自己的问题吗? - Abel
显示剩余2条评论
1个回答

2
问题在于没有将选项传递给search:snippet,而是传递给了search:parse
xquery version "1.0-ml";
module namespace searchlib="http://ihs.com/lib/searchlib";
import module namespace search="http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy"; 
import module namespace json="http://marklogic.com/xdmp/json" at "/MarkLogic/json/json.xqy";

declare function searchlib:get-snippet($docc,$words) {
  let $doc:= json:transform-from-json($docc)
  let $squery := search:parse($words,
<options xmlns="http://marklogic.com/appservices/search">
<term>
<term-option>case-insensitive</term-option>
<term-option>diacritic-insensitive</term-option>
</term>
</options>, "cts:query")

  let $result := <result>{search:snippet($doc,$squery,
  <transform-results apply="snippet" xmlns="http://marklogic.com/appservices/search">
          <max-snippet-chars>255</max-snippet-chars>

      </transform-results>)}</result>

  return $result//search:match
};

传递
<term-option>diacritic-insensitive</term-option>

使用search:parse解析后,search:snippet()可以正常工作。

以下是MarkLogic的解释:

search:snippet()函数允许您提取匹配的文本,并返回包含节点的匹配项,其中高亮显示已标记。但是,为了允许search:snippet提取正确的文本,应将传递给片段的cts:query()与值序列匹配。对于search:snippetcts:query通常是对search:parse调用的结果。 search:parse()函数根据给定的选项解析查询文本,并返回适当的cts:query XML。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接