簡體   English   中英

使用非拉丁字符搜索地名數據庫

[英]Searching Geoname database with non-latin characters

我有一個存儲在MySQL數據庫中的Geonames數據庫的副本,以及一個允許用戶在數據庫中搜索其城市的PHP應用程序。 如果他們用英語輸入城市名稱,效果很好,但我希望他們能夠使用其母語進行搜索。

例如,與其讓日語使用者搜索“ Tokyo東京讓他們搜索東京

Geonames數據庫包含一個“ alternatenames列,其中包含“ alternatenames, comma separated, ascii names automatically transliterated, convenience attribute from alternatename table, varchar(10000)

例如, Tokyo行的alternatenames值是Edo,TYO,Tochiu,Tocio,Tokija,Tokijas,Tokio,Tokió,Tokjo,Tokyo,Toquio,Toquio - dong jing,Toquio - æ±äº¬,Tòquio,Tókýó,Tóquio,TÅkyÅ,dokyo,dong jing,dong jing dou,tokeiyw,tokkiyo,tokyo,twkyw,twqyw,Τόκιο,Токио,ТокÑ',Токіо,ÕÕ¸Õ¯Õ«Õ¸,טוקיו,توكيو,توکیو,طوكيو,ܛܘܟÜܘ,ܜܘܟÜܘ,टोकà¥à¤¯à¥‹,டோகà¯à®•à®¿à®¯à¯‹,โตเà¸à¸µà¸¢à¸§,ტáƒáƒ™áƒ˜áƒ,东京,æ±äº¬,æ±äº¬éƒ½,ë„ì¿„

這些值不完全包含東京 ,但是我猜測它們包含以某種方式進行編碼或轉換的形式。 因此,我假設如果對搜索字符串執行相同的編碼/轉換,則可以匹配該行。 例如:

mysql_query( sprintf( "
    SELECT * FROM geoname 
    WHERE 
        MATCH( name, asciiname, alternatenames ) 
        AGAINST ( %s )  
    LIMIT 1",
    iconv( 'UTF-8', 'ASCII', '東京' )
) );

問題是我不知道這種轉換是什么。 我嘗試了很多iconv()mb_convert_string()等組合,但是沒有運氣。

MySQL表如下所示:

CREATE TABLE `geoname` (
 `geonameid` int(11) NOT NULL DEFAULT '0',
 `name` varchar(200) DEFAULT NULL,
 `asciiname` varchar(200) DEFAULT NULL,
 `alternatenames` mediumtext,
 `latitude` decimal(10,7) DEFAULT NULL,
 `longitude` decimal(10,7) DEFAULT NULL,
 `fclass` char(1) DEFAULT NULL,
 `fcode` varchar(10) DEFAULT NULL,
 `country` varchar(2) DEFAULT NULL,
 `cc2` varchar(60) DEFAULT NULL,
 `admin1` varchar(20) DEFAULT NULL,
 `admin2` varchar(80) DEFAULT NULL,
 `admin3` varchar(20) DEFAULT NULL,
 `admin4` varchar(20) DEFAULT NULL,
 `population` int(11) DEFAULT NULL,
 `elevation` int(11) DEFAULT NULL,
 `gtopo30` int(11) DEFAULT NULL,
 `timezone` varchar(40) DEFAULT NULL,
 `moddate` date DEFAULT NULL,
 PRIMARY KEY (`geonameid`),
 KEY `timezone` (`timezone`),
 FULLTEXT KEY `namesearch` (`name`,`asciiname`,`alternatenames`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4

誰能指出我正確的方向?

當我下載Japan文件並建立這樣的數據庫時:

CREATE TABLE geonames (
    geonameid SERIAL,
    name varchar(200),
    asciiname varchar(200),
    alternatenames varchar(10000),
    latitude float,
    longitude float,
    featureclass varchar(1),
    featurecode varchar(10),
    countrycode varchar(2),
    cc2 varchar(200),
    admin1code varchar(20),
    admin2code varchar(80),
    admin3code varchar(20),
    admin4code varchar(20),
    population BIGINT,
    elevation INT,
    dem INT,
    timezone varchar(40),
    modificationdate DATE
    ) CHARSET utf8mb4;

然后我像這樣加載數據

LOAD DATA INFILE '/tmp/JP.txt' INTO TABLE geonames CHARACTER SET utf8mb4;

然后選擇它:

SELECT alternatenames FROM geonames WHERE geonameid=1850147\G

我得到這個:

*************************** 1. row ***************************
alternatenames: Edo,TYO,Tochiu,Tocio,Tokija,Tokijas,Tokio,Tokió,Tokjo,Tokyo,Toquio,Toquio - dong jing,Toquio - 東京,Tòquio,Tókýó,Tóquio,Tōkyō,dokyo,dong jing,dong jing dou,tokeiyw,tokkiyo,tokyo,twkyw,twqyw,Τόκιο,Токио,Токё,Токіо,Տոկիո,טוקיו,توكيو,توکیو,طوكيو,ܛܘܟܝܘ,ܜܘܟܝܘ,टोक्यो,டோக்கியோ,โตเกียว,ტოკიო,東京,東京,東京都,도쿄

我也可以這樣搜索:

SELECT name FROM geonames WHERE alternatenames LIKE '%,東京,%';

長話大說:創建表時請注意字符集聲明。 我相信這是您創建數據庫時無法執行的操作。

推薦閱讀:

https://www.joelonsoftware.com/articles/Unicode.html

http://kunststube.net/encoding/


對於MySQL而言,至關重要的是MySQL連接的特征集。 這就是MySQL Server認為客戶端在其通信中使用的特征集。

SHOW VARIABLES LIKE '%characterset%'

例如,如果設置不正確,則客戶端正在發送latin1(ISO-8859-1),但是MySQL服務器認為它正在接收UTF8,反之亦然,則有可能進行mojibake。

alternatenames列的字符集也很重要。


處理多字節字符集的一個問題將是PHP sprintf函數。 PHP中的許多字符串處理函數都有“ mutlibyte”等效項,可以正確處理包含多字節字符的字符串。

https://secure.php.net/manual/zh/book.mbstring.php

不幸的是,沒有內置的mb_sprintf函數。

有關PHP中字符串處理(包括多字節字符/字符集)的更詳細描述:

https://secure.php.net/manual/zh-CN/language.types.string.php#language.types.string.details

摘抄:

最終,這意味着使用Unicode編寫正確的程序取決於謹慎地避免使用那些無法正常工作並且很可能會破壞數據的函數,而應使用通常從intl和mbstring擴展名正確執行的函數。 但是,使用可以處理Unicode編碼的功能只是開始。 無論語言提供的功能如何,了解Unicode規范都是必不可少的。

另外,谷歌搜索“ utf8一直到”可能會返回一些有用的注釋。 但請注意,此口頭禪不是解決問題的靈丹妙葯。


MySQL參考手冊中指出了另一個可能的問題:

https://dev.mysql.com/doc/refman/5.7/zh-CN/fulltext-restrictions.html

13.9.5全文限制

表意語言(例如中文和日語)沒有單詞定界符。 因此,內置的全文語法分析器無法確定單詞在這些語言和其他此類語言中的開始和結束位置。

在MySQL 5.7.6中,提供了可支持InnoDB和MySIAM表的支持中文,日文和韓文(CJK)的基於字符的ngram全文分析器,以及支持日文的基於單詞的MeCab解析器插件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM