如何在元素中进行多项搜索

时间:2013-08-15 16:43:26

标签: xquery marklogic

我正在尝试进行搜索,检查查询字符串中的每个单词是否包含在特定元素中。例如,如果$query = "Sports With Stripes"那么特定元素必须包含所有三个单词(以任何顺序,所以它不是短语)。

要限制搜索元素,我有以下约束:

        <constraint name="inelement">
            <word>
                <element ns="" name="myElement"/>
                <term-option>case-insensitive</term-option>
            </word>
        </constraint>

这似乎没问题,但是当涉及到search:search的内容时,我正在努力。我第一次尝试这个:

search:search('inelement:spots with stripes', $options, 1, 25)

这不起作用,因为它只会将"spots"限制为我的元素。

然后我尝试了以下内容,它确实为我提供了我需要的结果,但我想知道这是否是实现此目的的唯一方法,或者是否有其他方法,例如在我的搜索词之间使用运算符。

search:search('inelement:spots inelement:with inelement:stripes', $options, 1, 25)

有更好的方法吗?或者,在将约束添加到search:search之前,我是否需要手动解析queryString以将它们分成单个单词?

2 个答案:

答案 0 :(得分:1)

要在空格中应用约束,请使用引号。

inelement:"spots with stripes"

使用默认解析器返回单个元素 - 单词术语。要将术语分解为单词,您可以编写自定义解析器函数。 http://docs.marklogic.com/guide/search-dev/search-api#id_49750

有一个例子

您可能希望cts:near-query确保所有三个字都在相同的元素中。您可能需要在数据库配置中启用element-word-positions

答案 1 :(得分:0)

您可以使用search:searchsearch:parse的组合代替search:resolve,并在两者之间进行自定义处理。如果您希望始终在特定元素中进行搜索,则可以在这些步骤之间更新查询。

declare function local:word-to-element-query(
  $element as xs:QName,
  $query as item()
) as item()
{
  typeswitch ($query)
  case element(cts:word-query)
    return cts:element-word-query($element, 
      $query/cts:text/string(),
      $query/cts:option/string())
  case text() return $query
  default return 
    element { node-name($query) } {
      $query/@*, local:word-to-element-query($element, $query/node())
    }
};

let $query := 
  local:word-to-element-query(
    xs:QName('myElement'),
    search:parse('spots with stripes'))
return search:resolve($query)

递归typeswitch模板是修改默认解析输出和添加其他自定义逻辑的好策略。