2016-07-29 66 views
1

我們使用Marklogic 8.0-3,而且我們的數據庫有很多包含「麥當勞」和「麥當勞」的文檔。在搜索「麥當勞」或「麥當勞」時,我期望得到相同的結果。但即使我將它們設置爲標點符號不敏感,它們也不會給出相同的結果。用撇號Marklogic關鍵字搜索

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

您的問題與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,這樣你可以刪除索引中的撇號;不過,您可能仍然處於搜索輸入消毒的狀態,並且根據您的應用程序,可能會有其他意想不到的副作用。

0

這裏發生的事情:

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

表明,長期被分解成

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

所以我們看到,單引號是標點項,而且「S」是一個獨立的字。對於數據攝取和查詢,標記化發生相同。現在的問題是這兩個東西是否應該匹配:

  • (CTS:字( 「麥當勞」),CTS:標點符號( 「' 」),CTS:字(「 S」))
  • CTS:字(「麥當勞」)

他們不這樣做,你可能會猜到。標點符號在這裏被忽略,但這仍然讓我們試圖匹配「麥當勞」,其次是「s」和「麥當勞」。我不認爲有任何選項可以解決這個問題。

對於您如何解決這個問題,我有三點想法。

  1. 在數據加載時,應用信封模式。從<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> 

現在的「麥當勞」將在本文檔匹配搜索。

  1. 使用語義來跟蹤「McDonalds」和「McDonald's」是同一件事並且做運行時查詢擴展(在運行時,做一個SPARQL查詢來查看是否存在任何同義詞爲您搜索的條款;如果是這樣,擴大與這些條款搜索)
  2. 使用Thesaurus functionality做運行時查詢擴展