我有一个“已知短语”列表,存储在XML文档中名为 label 的元素下。我试图弄清楚如何编写一个函数,可以将搜索短语标记为所有标签部分(如果可用)。
例如。我有朝鲜的标签和ICBM。
如果用户输入朝鲜洲际弹道导弹,我会期望获得两个代币,每个标签一个,而不是朝鲜和朝鲜以及洲际弹道导弹。 在另一个例子中,如果用户键入纽约市,我预计只有一个“纽约市”的标记(标签)。
如果找不到标签,它将返回每个单词的默认标记化。
我试着开始编写这个,但是我不知道如何在没有while循环工具的情况下正确地执行此操作,并且我对xQuery一般都是新手。
下面的代码是我的开始,但很快意识到它不适用于扩展搜索字词。 基本上,它会检查完整短语是否在标签字段中。如果不是,它会从搜索短语的背面开始剥离,检查标签的剩余部分。
let $label-query := cts:element-value-query(fn:QName('','label'), $searchTerm, ('case-insensitive', 'whitespace-sensitive'))
let $results := cts:search(fn:collection('typea'),$label-query)
let $test :=
if (fn:empty($results)) then
let $tokens := (fn:tokenize($searchTerm, " "))
let $tokenCount := fn:count($tokens)
let $lastWord := $tokens[last()]
let $firstPhrase := $tokens[position() ne (last())]
let $_ :=
if (fn:count($firstPhrase) = 1 ) then
()
else
let $label-query2 := cts:element-value-query(fn:QName('','label'), $firstPhrase, ('case-insensitive', 'whitespace-sensitive'))
let $results2 := cts:search(fn:collection('typea'),$label-query2)
return
if (fn:empty($results2)) then
xdmp:log('second empty')
else
xdmp:log($results2)
let $l := xdmp:log( $firstPhrase )
return $tokens
else
let $_ := xdmp:log('full')
return element {'result'} {$results}
有没有人有任何建议我如何递归地实现这个或者任何替代策略。我基本上试图说,将这句话分解为 typea 集合的标签字段中存在的所有短语。如果找不到标签,请按字标记。
谢谢,我期待着您的指导。
更新以帮助澄清我的最终目的。
以下是涉及朝鲜的文件。
目标是解析搜索词组,并使用这些文档中的额外信息来帮助搜索。
如果此人输入 DPRK 或朝鲜,则他们应该以相同的方式搜索。它还应该包含 Narrower 标签作为搜索的条件或条件,并且更有可能不会更新以包含也将包含在搜索中的其他关系。 (IE:Kim Jong Un特别与朝鲜有联系。)
因此,简而言之,我想使用标签字段协调多短语搜索字词,然后如果找到它,请使用所有标签 +中的信息较窄的标签以及该文档。
编辑2:尝试使用cts:highlight
来获取短语。一旦我有了短语,我将进行元素查找以获取正确的文档,然后获取相关的文档数据以提交给查询构建。
现在的问题是cts:highlight并不总是返回一个<phrase>
标记下的完整短语。
let $phrases := cts:highlight(<nod>New York City FC</nod>, cts:or-query((//label)), <phrase>{ $cts:text }</phrase>)
答案 0 :(得分:3)
如果您使用MarkLogic 9,可能的替代方法是设置自定义标记化字典。有关详细信息,请参阅自定义词典API文档1并搜索开发人员指南2。
但要点是,如果你添加一个条目&#34;朝鲜&#34;在您的语言的标记化词典中,您将其作为该语言的单个标记获取。这将适用于所有地方:内容或搜索。
也就是说,从你的代码中可以清楚地知道你最终想要实现的目标。如果使用短语搜索更准确,那么有更好的方法可以实现这一点(为2个单词短语启用快速短语,或为较长的短语启用单词位置)。
如果我们只讨论搜索解析,你仍然可以使用标记化字典方法,但是你可能想要使用特殊的语言代码,这样它就不会弄乱你的实际内容,然后使用{{ 1}},例如cts:tokenize
其中cts:tokenize("North Korea ICBM","xen")
是您的特殊语言代码。
另一种方法是使用"xen"
将标记应用于匹配字符串中的短语并从那里开始:
cts:highlight
这将为任何匹配的短语嵌入标记:cts:highlight(<node>North Korea ICBM</node>,
cts:or-query((//label)),
<phrase>{$cts:text}</phrase>)
如果你想强迫一个特定的胜利者,通过应用你想先获胜的套装,然后再与其他人一起运行第二次传球,必须注意重叠。