0

我正在尝试进行搜索以检查查询字符串中的每个单词是否包含在特定元素中。例如,如果 the$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)

有没有更好的办法?或者在将约束添加到我的之前,我是否必须手动解析我的 queryString 以将它们分成单独的单词search:search

4

2 回答 2

1

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

inelement:"spots with stripes"

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

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

于 2013-08-15T19:10:18.717 回答
0

而不是search:search您可以使用 and 的组合,search:parsesearch: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)

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

于 2013-08-15T17:01:51.220 回答