Python / PHP SQLite在FTS4 / FTS5中查询波兰字母Ł/ł

时间:2018-08-16 10:39:28

标签: php python sqlite tokenize fts4

由于SQLite FTS4 / FTS5 tokenizer = unicode61为我们提供了

a=A=ą=Ą=ä=Ä ...
z=ż=ź=Z=Ż=Ź=Ž=ž ...
etc...

为什么不l =ł= L =Ł???不是虫子吗?

如何在没有波兰字符ł/Ł的键盘上查询SQLite?例如,查询名称Żabczyński,例如“ zabczynski”-得到结果,但查询名称Włast,例如“ wlast”-0结果(应该是数百个...) 我在PHP中有自己的解决方法,但是它不能处理其中带有l和ł的单词,例如“opłacalny”。

<?
$q = $_POST["q"];
//
$pat = '/(\b\w*[lł]\w*\b)/iu';
    $q = preg_replace_callback($pat,function($macz){
        return "(" . str_replace("ł","l",$macz[1]) . "* OR " . str_replace("l","ł",$macz[1]) . "*)";
    },$q);
// so query 'andrzej wlast' looks 'andrzej (wlast* OR włast*)'
...
    $sql = "SELECT ...";
    $pdo = $db->prepare($sql);
    //
    $pdo->execute([":q" => "$q*"]);
    //
    $odp = $pdo->fetchAll(PDO::FETCH_ASSOC);
?>

有什么主意吗?您无法在utf8_general_ci,utf8_polish_ci,utf8_unicode_ci等sqlite中设置编码。还是可以,

有没有办法用Python解决它?平台(共享服务器)上没有ICU。

2 个答案:

答案 0 :(得分:1)

不幸的是,不,SQLite没有像MySQL这样的整理表,因为它会肿本来应该是一个很小的可移植库。

您可以将查询转换为以下内容:

SELECT * FROM foo WHERE word REGEXP '^[ZŻ]abczy[nń]ski$';
SELECT * FROM foo WHERE word REGEXP '^W[lł]ast$';

在Python中这很简单:

def collatify(string, equivalents):
    for original, replacement in equivalents.items():
        string = string.replace(original, '[%s%s]' % (original, replacement))
    return string

collatify('Żabczyński', { "Ż": "Z", "ń": "n" })

不幸的是,这将使得无法在这些字段上使用索引进行搜索。

一种更好的方法是执行相反的操作,“关联”您的字符串,并将其作为附加列输入数据库(带有自己的索引!);然后“关联”您的查询,并观察其工作情况。更好的是,查看您的“关联”查询是否与原始查询相同;如果是,请使用“已关联”列(仅当用户输入ASCII字符时);如果它们不同,则用户输入了波兰语专用字符,并且可能会正确输入所有字符,因此请使用原始列。这样,如果用户输入“Żabczyński”,则可以在原始列中搜索“Żabczyński”并在此处找到它。如果用户输入“ Zabczynski”,则假设它已被关联,并在关联列中搜索;如果他们在那里,则会找到“Żabczyński”,“Zabczyński”,“Żabczynski”和“ Zabczynski”。如果用户输入“Zabczyński”或“Żabczynski”,则大概他们应该知道波兰语,因此请在原始列中搜索,不返回任何结果。所有这些胜利的代价是仅再存储一列您的列。

答案 1 :(得分:0)

移至MySQL或Postgres。 SQLite有其局限性。