【问题标题】:MarkLogic - Tokenize Search Phrase based on XML Field as a dictionary of phrasesMarkLogic - 基于 XML 字段将搜索短语标记为短语字典
【发布时间】:2018-01-22 08:57:37
【问题描述】:

我有一个存储在 XML 文档中名为 label 的元素下的“已知短语”列表。我正在尝试弄清楚如何编写一个函数,该函数可以将搜索短语标记为其所有 label 片段(如果可用)。

例如。我有朝鲜和洲际弹道导弹的标签。

如果用户键入 North Korea ICBM,我希望得到两个令牌,一个用于每个标签,而不是 North and Korea 和 ICBM。 在另一个示例中,如果用户键入纽约市,我希望只有一个“纽约市”的标记(标签)。

如果没有找到标签,它将返回每个单词的默认标记。

我尝试开始编写此代码,但不确定如何在没有 while 循环工具的情况下正确执行此操作,并且总体上对 xQuery 还是很陌生。

下面的代码是我开始的,但很快意识到它不适用于扩展搜索词。 基本上,它会检查完整的短语是否在 Label 字段中。如果不是,它开始从搜索短语的后面剥离,检查标签的剩余内容。

  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 集合的 Label 字段中的短语。如果没有找到标签,则按单词进行标记。

谢谢,期待您的指导。


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

以下是指朝鲜的文件。

目标是解析搜索短语,并使用在这些文档中找到的额外信息来帮助搜索。

意思是如果用户输入 DPRKNorth Korea,他们应该以相同的方式进行搜索。它还应该包含 Narrower 标签作为搜索的 Or 条件,并且很可能会更新以包含也将包含在搜索中的其他关系。 (即:金正恩与朝鲜有着明显的联系。)

所以简而言之,我想使用 label 字段来协调多短语搜索词,然后如果找到,请使用 all labels + 中的信息更窄的标签以及来自该文档。


编辑 2:尝试使用 cts:highlight 获取短语。获得短语后,我将进行元素查找以找到正确的文档,然后获取关联的文档数据以提交到查询构建。

现在的问题是 cts:highlight 并不总是在一个 <phrase> 标记下返回完整的短语。

let $phrases :=   cts:highlight(<nod>New York City FC</nod>,      cts:or-query((//label)),      <phrase>{ $cts:text }</phrase>)

【问题讨论】:

    标签: nlp marklogic


    【解决方案1】:

    如果您使用 MarkLogic 9,另一种可能的方法是设置自定义标记化字典。详见自定义字典 ​​API 文档1 和搜索开发者指南2

    但要点是,如果您在标记化字典中为一种语言添加条目“朝鲜”,您将把它作为该语言的单个标记取回。这将适用于任何地方:内容或搜索。

    也就是说,从您的代码中并不清楚您最终要达到什么目的。如果词组搜索更准确,则有更好的方法来实现这一点(为 2 个词的词组启用快速词组,或为较长的词组启用词位)。

    如果我们只讨论搜索解析,您仍然可以使用标记化字典方法,但您可能希望为其使用特殊的语言代码,以免弄乱您的实际内容,然后使用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>)
    

    这将嵌入任何匹配短语的标记:&lt;node&gt;&lt;phrase&gt;North Korea&lt;/phrase&gt;&lt;/node&gt;

    如果您想通过应用您想首先赢得的那组,然后与其他人一起运行第二次传球来强制获得特定的获胜者,则必须注意重叠。

    【讨论】:

    • 嗨@mholstege 感谢您的指导。我围绕我的最终意图用一些额外的颜色更新了我的问题。目标确实是搜索解析,但它也想在解析后将找到的文档中的额外字段添加到搜索中
    • 我也在考虑在该领域使用词典来提供帮助
    • 看起来我无法使自定义标记化或词典查找正常工作,因为短语往往是复合的......我也尝试了突出显示策略,但不起作用。在“纽约市洲际弹道导弹”之类的情况下,每个单词都用自己的 &lt;phrase&gt; 包裹起来,而我仍然只期望 2 phrases
    • 我意识到为什么cts:highlight 不能正常工作。我相信可能是case sensitivity。有没有办法在那个突出显示的上下文中忽略大小写敏感?....编辑:nm,仍然将其拆分-_-
    • 为您的单词查询添加适当的选项,例如“区分大小写”或“不区分大小写”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多