我正在尝试进行搜索,检查查询字符串中的每个单词是否包含在特定元素中。例如,如果$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以将它们分成单个单词?
答案 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:search
和search: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模板是修改默认解析输出和添加其他自定义逻辑的好策略。