我在建立從GeoNames.com導入的城市名稱搜索。一些城市在名稱中具有國際性特徵。例如,「伊斯坦布爾」實際上是數據庫中的「伊斯坦布爾」。在Django查詢中處理外國字符
當人們搜索「伊斯坦布爾」時,伊斯坦布爾不會出現。
有沒有一種方法可以讓我一個過濾器或解碼器添加到搜索會知道,伊斯坦布爾=伊斯坦布爾
目前,它的:
cities = City.objects.filter(name__icontains=query)
我在建立從GeoNames.com導入的城市名稱搜索。一些城市在名稱中具有國際性特徵。例如,「伊斯坦布爾」實際上是數據庫中的「伊斯坦布爾」。在Django查詢中處理外國字符
當人們搜索「伊斯坦布爾」時,伊斯坦布爾不會出現。
有沒有一種方法可以讓我一個過濾器或解碼器添加到搜索會知道,伊斯坦布爾=伊斯坦布爾
目前,它的:
cities = City.objects.filter(name__icontains=query)
Unidecode將幫助你解決這個問題的某種形式。 Unidecode將非ASCII字符轉換爲ASCII碼,例如:
>>> from unidecode import unidecode
>>> unidecode(u"İstanbul")
'Istanbul'
您可以通過分解Unicode字符和拆卸組合變音符號達到類似的效果。這種技術的問題是某些字符不可分解。所以,當「ö」分解爲「o」和變音符號時,「Ł」(L-stroke)將保持不變。 Unidecode成功將「英鎊」翻譯爲「L」。
但Undeicode不能解決您的所有問題;城市可以通過不同的名字被知道,或者這些名字可以寫成不同的名字。例如,在美國我們稱之爲中國的「北京」的資本,但是我們習慣稱之爲「北平」(它仍然被稱爲「北平」,在瑞典語),並與unidecode
翻譯它的名字別人給我們的東西:
>>> unidecode(u"\u5317\u4EB0")
'Bei Jing '
最好的解決辦法是有名字的特定語言的列表,而不是使用城市的實際名稱。
我不認爲有什麼準備爲它在Django。
我會在數據庫中創建一個單獨的列,名稱與NameCombinations類似,我將把所有可能的組合,例如,伊斯坦布爾İstanbul並將查詢
cities = City.objects.filter(NameCombinations__icontains=query)
我同意你最好的選擇是保持備用拼寫列表。 – monkut
如果沒有關於您想要什麼行爲的更多信息,很難給出確切的建議。
但是,一個明顯的步驟是爲每個名稱(小寫,無重音等)定義規範形式,並將名稱的規範形式存儲在數據庫的第二列中,除了正確名稱。然後將搜索字符串映射到規範形式。因此,「伊斯坦布爾」可能是「伊斯坦布爾」的標準形式。
另一個顯而易見的步驟是將城市名稱與其餘有關城市的信息分開成單獨的表格。這讓每個城市都有幾個名字,即同義詞。然後,對於每個城市名稱,根據需要定義許多同義詞,以捕捉用戶喜歡的不同拼寫。例如,您可以輸入「伊斯坦布爾」和「イスタンブル」作爲「伊斯坦布爾」的同義詞。
你當然可以同時使用這兩種方法。
一旦在數據庫中設置了適當的排序規則,比較就會按照您的要求進行。
當你說「目前,它是」,你的意思是,「目前,搜索操作是由這個代碼實現的:」? –
你想要什麼樣的行爲?你想讓不重複的拉丁字母與重音拉丁字母匹配嗎?您是否想要音譯(例如搜索日語「イスタンブル」)?怎麼拼錯?你關心搜索結果返回的順序嗎? –
什麼是數據庫整理和連接整理? –