使用撇号进行Marklogic关键字搜索

时间:2016-07-29 02:48:12

标签: marklogic apostrophe marklogic-8

我们使用Marklogic 8.0-3,我们的数据库有很多文件包含" McDonalds"和"麦当劳"。在寻找" McDonalds"或者"麦当劳",我期待相同的结果。但即使我将它们设置为标点符号不敏感,它们也不会给出相同的效果。

search:search("McDonalds", 
  <options xmlns="http://marklogic.com/appservices/search">
    <term>
      <term-option>case-insensitive</term-option>
      <term-option>diacritic-insensitive</term-option>
      <term-option>punctuation-insensitive</term-option>
    </term>
  </options>
)

search:search("McDonald's", 
  <options xmlns="http://marklogic.com/appservices/search">
    <term>
      <term-option>case-insensitive</term-option>
      <term-option>diacritic-insensitive</term-option>
      <term-option>punctuation-insensitive</term-option>
    </term>
  </options>
)

目前,第一个搜索查询返回2个结果,第二个查询返回79个结果。有没有办法搜索关键字并忽略撇号?

2 个答案:

答案 0 :(得分:0)

您的问题与MarkLogic中标记词的方式有关。分隔字符串的空格或标点符号会将这些字符解析为单独的标记。在你的问题中:

xdmp:describe(cts:tokenize("McDonald's"))
=>
(cts:word("McDonald"), cts:punctuation("'"), cts:word("s"))

McDonald's被视为由标点符号分隔的两个单词标记组成的短语。当您调用punctuation-insensitive选项时,它将忽略标点符号,但它不会加入令牌来执行此操作。例如:

cts:contains("McDonald+=?%s", cts:word-query("McDonald's", "punctuation-insensitive"))
=>
true

cts:contains("McDonalds", cts:word-query("McDonald's", "punctuation-insensitive"))
=>
false

如果你只有这样的单词数量有限,我建议使用thesaurus functions that ship with MarkLogic扩展任意一个词的搜索。

它也可以create override rules for MarkLogic's tokenizer,这样你就可以删除索引中的撇号;但是,您仍然可能会对搜索输入进行消毒处理,并且可能会出现其他意外的副作用,具体取决于您的应用程序。

答案 1 :(得分:0)

这里发生了什么:

xdmp:describe(cts:tokenize("McDonald's"))

表明该术语已分解为

(cts:word("McDonald"), cts:punctuation("'"), cts:word("s"))

所以我们看到单引号是一个标点术语,并且&#34; s&#34;是一个单独的词。对于数据摄取和查询,标记化都是相同的。问题是这两件事是否应该匹配:

  • (cts:word(&#34; McDonald&#34;),cts:标点符号(&#34;&#39;&#34;),cts:word(&#34; s&#34;))
  • CTS:字(&#34;麦当劳&#34)

他们没有,你可能会猜到。标点符号在这里被忽略了,但这仍然让我们试图匹配&#34;麦当劳&#34;其次是&#34; s&#34;反对&#34;麦当劳。&#34;我认为任何一套选择都无法解决这个问题。

对于你如何解决这个问题,我有三个想法。

  1. 关于数据加载,应用信封模式。从<fast-food>McDonalds</fast-food>开始,添加<fast-food>McDonald's</fast-food>
  2. 假设您的原始文档是

    <doc>
      <fast-food>McDonalds</fast-food>
    </doc>
    

    您可以应用转换来改为:

    <envelope>
      <meta>
        <fast-food>McDonald's</fast-food>
      </meta>
      <doc>
        <fast-food>McDonalds</fast-food>
      </doc>
    </envelope>
    

    现在搜索&#34;麦当劳&#34;将匹配此文档。

    1. 使用语义来追踪&#34; McDonalds&#34;和麦当劳&#34;麦当劳&#34;是相同的事情并进行运行时查询扩展(在运行时,执行SPARQL查询以查看搜索中是否有任何同义词;如果是,请使用这些术语展开搜索)
    2. 使用Thesaurus functionality进行运行时查询扩展