我们使用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个结果。有没有办法搜索关键字并忽略撇号?
答案 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;是一个单独的词。对于数据摄取和查询,标记化都是相同的。问题是这两件事是否应该匹配:
他们没有,你可能会猜到。标点符号在这里被忽略了,但这仍然让我们试图匹配&#34;麦当劳&#34;其次是&#34; s&#34;反对&#34;麦当劳。&#34;我认为任何一套选择都无法解决这个问题。
对于你如何解决这个问题,我有三个想法。
<fast-food>McDonalds</fast-food>
开始,添加<fast-food>McDonald's</fast-food>
。 假设您的原始文档是
<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;将匹配此文档。