MarkLogic - 基于XML Field的Tokenize Search Phrase作为短语词典

时间:2017-08-14 13:40:18

标签: nlp marklogic

我有一个“已知短语”列表,存储在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 集合的标签字段中存在的所有短语。如果找不到标签,请按字标记。

谢谢,我期待着您的指导。

更新以帮助澄清我的最终目的。

以下是涉及朝鲜的文件。

enter image description here

目标是解析搜索词组,并使用这些文档中的额外信息来帮助搜索。

如果此人输入 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>)

enter image description here

1 个答案:

答案 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>)

如果你想强迫一个特定的胜利者,通过应用你想先获胜的套装,然后再与其他人一起运行第二次传球,必须注意重叠。