带撇号的Marklogic关键字搜索

带撇号的Marklogic关键字搜索,marklogic,apostrophe,marklogic-8,Marklogic,Apostrophe,Marklogic 8,我们使用Marklogic 8.0-3,我们的数据库中有很多包含“麦当劳”和“麦当劳”的文档。在搜索“麦当劳”或“麦当劳”时,我希望得到相同的结果。但即使我将它们设置为标点不敏感,它们也不会给出相同的结果 search:search("McDonalds", <options xmlns="http://marklogic.com/appservices/search"> <term> <term-option>case-insens

我们使用Marklogic 8.0-3,我们的数据库中有很多包含“麦当劳”和“麦当劳”的文档。在搜索“麦当劳”或“麦当劳”时,我希望得到相同的结果。但即使我将它们设置为标点不敏感,它们也不会给出相同的结果

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>
)
search:search(“麦当劳”,
不区分大小写
变音不敏感
标点不敏感
)
搜索:搜索(“麦当劳”,
不区分大小写
变音不敏感
标点不敏感
)

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

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

xdmp:describe(cts:tokenize("McDonald's"))
=>
(cts:word("McDonald"), cts:punctuation("'"), cts:word("s"))
McDonald's
被视为一个短语,由两个单词标记(由标点符号分隔)组成。当您调用
标点符号不敏感
选项时,它将忽略标点符号,但不会加入标记来忽略标点符号。例如:

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

cts:contains("McDonalds", cts:word-query("McDonald's", "punctuation-insensitive"))
=>
false
如果像这样的单词数量有限,我建议您使用展开搜索以查找任一术语


也可以删除索引中的撇号;但是,您可能仍然需要清理搜索输入,并且根据您的应用程序,这样做可能会产生其他意外的副作用。

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

xdmp:describe(cts:tokenize("McDonald's"))
=>
(cts:word("McDonald"), cts:punctuation("'"), cts:word("s"))
McDonald's
被视为一个短语,由两个单词标记(由标点符号分隔)组成。当您调用
标点符号不敏感
选项时,它将忽略标点符号,但不会加入标记来忽略标点符号。例如:

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

cts:contains("McDonalds", cts:word-query("McDonald's", "punctuation-insensitive"))
=>
false
如果像这样的单词数量有限,我建议您使用展开搜索以查找任一术语


也可以删除索引中的撇号;但是,您可能仍然需要对搜索输入进行清理,根据您的应用程序,这样做可能会产生其他意外的副作用。

下面是发生的情况:

xdmp:describe(cts:tokenize("McDonald's"))
表示该术语被分解为

(cts:word("McDonald"), cts:punctuation("'"), cts:word("s"))
所以我们看到单引号是一个标点符号术语,“s”是一个单独的单词。标记化对于数据摄取和查询都是一样的。问题是这两件事是否应该匹配:

  • (cts:单词(“麦当劳”)、cts:标点符号(“麦当劳”)、cts:单词(“麦当劳”))
  • cts:word(“麦当劳”)
正如你可能猜到的,他们没有。这里的标点符号被忽略了,但这仍然让我们试图将“麦当劳”和“麦当劳”匹配起来。我不认为任何选项都能解决这个问题

关于如何解决这个问题,我有三个想法

  • 在数据加载时,应用信封模式。从
    麦当劳
    ,添加
    麦当劳
    假设您的原始文档是

    <doc>
      <fast-food>McDonalds</fast-food>
    </doc>
    
    
    麦当劳
    
    您可以应用一个转换,使其变成这样:

    <envelope>
      <meta>
        <fast-food>McDonald's</fast-food>
      </meta>
      <doc>
        <fast-food>McDonalds</fast-food>
      </doc>
    </envelope>
    
    
    麦当劳
    麦当劳
    
    现在搜索“麦当劳”将匹配此文档

  • 使用语义跟踪“麦当劳”和“麦当劳”是同一事物,并执行运行时查询扩展(在运行时,执行SPARQL查询以查看搜索中是否存在术语的同义词;如果是,则使用这些术语扩展搜索)
  • 使用执行运行时查询扩展

  • 下面是正在发生的事情:

    xdmp:describe(cts:tokenize("McDonald's"))
    
    表示该术语被分解为

    (cts:word("McDonald"), cts:punctuation("'"), cts:word("s"))
    
    所以我们看到单引号是一个标点符号术语,“s”是一个单独的单词。标记化对于数据摄取和查询都是一样的。问题是这两件事是否应该匹配:

    • (cts:单词(“麦当劳”)、cts:标点符号(“麦当劳”)、cts:单词(“麦当劳”))
    • cts:word(“麦当劳”)
    正如你可能猜到的,他们没有。这里的标点符号被忽略了,但这仍然让我们试图将“麦当劳”和“麦当劳”匹配起来。我不认为任何选项都能解决这个问题

    关于如何解决这个问题,我有三个想法

  • 在数据加载时,应用信封模式。从
    麦当劳
    ,添加
    麦当劳
    假设您的原始文档是

    <doc>
      <fast-food>McDonalds</fast-food>
    </doc>
    
    
    麦当劳
    
    您可以应用一个转换,使其变成这样:

    <envelope>
      <meta>
        <fast-food>McDonald's</fast-food>
      </meta>
      <doc>
        <fast-food>McDonalds</fast-food>
      </doc>
    </envelope>
    
    
    麦当劳
    麦当劳
    
    现在搜索“麦当劳”将匹配此文档

  • 使用语义跟踪“麦当劳”和“麦当劳”是同一事物,并执行运行时查询扩展(在运行时,执行SPARQL查询以查看搜索中是否存在术语的同义词;如果是,则使用这些术语扩展搜索)
  • 使用执行运行时查询扩展