在搜索的帮助下,我无法提供这种简单的自动完成功能:建议功能。
基于来自Marklogic演示数据的奥斯卡语料库,我尝试提供一个建议查询,例如即使用户正在写“Robert Lo”或“Loggia Rob”,也可以将“Robert Loggia”作为答案返回甚至是“L Rob”。
目前,我只能通过这个简单的查询在他的一些同行中返回“Robert Loggia”:
let $options :=
<options xmlns="http://marklogic.com/appservices/search">
<default-suggestion-source>
<range type="xs:string">
<element ns="http://marklogic.com/wikipedia" name="name" />
</range>
</default-suggestion-source>
</options>
return search:suggest("Rob",$options)
但是一旦我写了两个单词的短语,我就不太明白如何写这个,因为没有一个答案对我正在等待的是正确的。例如:
search:suggest("Robert Lo",$options)
或
search:suggest(("Robert", "Lo"),$options)
是否由于缺少选项,索引错误配置或误用功能?
感谢您的帮助
答案 0 :(得分:3)
这是grammar-aware
。
如果您想获得有关该词组的建议,则需要在该词组周围添加引号,否则它会单独处理该令牌。请尝试以下方法:
search:suggest('"Robert Lo"',$options)
答案 1 :(得分:2)
这是一个常见的错误,我自己做了好几次。
正如科琳所说,你需要在查询字符串周围加上引号。这与使用搜索API进行一般搜索相同,或谷歌就此问题:使用引号将您的参数视为短语,并且每个标记都不是单独的参数。
如果没有引号,默认行为是将两个术语视为单独的标记,并在查询中将它们与AND或OR一起考虑,具体取决于您的配置。
答案 2 :(得分:1)
对我来说也很奇怪,在OS X上使用4.2-6。这是我的测试中使用完整的oscars数据集的结果。
import module namespace search = "http://marklogic.com/appservices/search"
at "/MarkLogic/appservices/search/search.xqy";
let $options :=
<options xmlns="http://marklogic.com/appservices/search">
<default-suggestion-source>
<range type="xs:string">
<element ns="http://marklogic.com/wikipedia" name="name" />
</range>
</default-suggestion-source>
</options>
return search:suggest("Robert Lo", $options)
=>
Robert "Loretta Young"
Robert "Lorraine Bracco"
Robert "Lotte Lenya"
Robert "Louis Calhern"
Robert "Louis Gossett, Jr."
Robert "Louis Malle"
Robert "Louise Fletcher"
看起来为or-query(('Robert','Lo'))生成了值,然后以奇怪的方式合并。如果我们下降到使用cts词典功能,事情看起来很正常。
cts:element-value-match(
QName('http://marklogic.com/wikipedia', 'name'),
'Robert Lo*')
=>
Robert Loggia
单词交换方面使事情变得更加复杂,并且超出了autosuggest通常所做的范围(以及search:suggest
和cts:element-value-match
可以在没有帮助的情况下做什么)。
这是一个使用额外字符串操作来创建两个模式,处理单词对的版本。它假定第一个单词总是完整的,而第二个单词可能是一个存根,但是这些单词可能需要交换匹配。如果您定义了所需的逻辑,则应该能够根据您的要求进行修改。请注意,函数映射正在运行,因此在评估期间每个模式调用cts:element-value-match
一次。这可能会对性能产生影响。
let $toks := cts:tokenize($INPUT)[. instance of cts:word]
let $pat := (
if (count($toks) eq 1) then concat($toks, '*')
else (
concat($toks[2], '* ', $toks[1]),
concat($toks[1], ' ', $toks[2], '*')))
return cts:element-value-match(
QName('http://marklogic.com/wikipedia', 'name'),
$pat)
=>
Robert Loggia