对搜索感到困惑:建议

时间:2011-09-01 14:03:05

标签: marklogic

在搜索的帮助下,我无法提供这种简单的自动完成功能:建议功能。

基于来自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)

是否由于缺少选项,索引错误配置或误用功能?

感谢您的帮助

3 个答案:

答案 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:suggestcts: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