Python / PHP SQLite запрашивает польскую букву Ł / ł в FTS4 / FTS5

Поскольку 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);
?>

Любая идея? Вы не можете установить кодировку в sqlite, например, utf8_general_ci, utf8_polish_ci, utf8_unicode_ci … Или да, это возможно?

Есть ли способ решить это в Python? Нет ICU на платформе (общий сервер).

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" })

Опять же, к сожалению, это сделает невозможным использование индексов для поиска по этим полям.

Лучший подход — выполнить противоположную операцию, «оценить» ваши строки и ввести их в базу данных в качестве дополнительного столбца (со своим собственным индексом!); затем «оцените» ваш запрос и посмотрите, как он работает. Еще лучше посмотреть, совпадает ли ваш «уточненный» запрос с оригиналом; если это так, используйте столбец «asciified» (поскольку пользователь вводил только символы ASCII); если они различаются, то пользователь вводит специфичные для польского языка символы и, вероятно, введет их все правильно, поэтому используйте исходный столбец. Таким образом, если пользователь вводит «Żabczyński», вы ищете «Żabczyński» в исходном столбце и находите его там. Если пользователь вводит «Zabczynski», предположим, что он может быть увеличен, и искать в столбце уточненного; он нашел бы «Żabczyński», «Zabczyński», «Żabczynski» и «Zabczynski», если бы они были там. Если пользователь вводит «Zabczyński» или «Żabczynski», предположительно они должны знать польский язык, поэтому ищите в исходном столбце и не возвращайте результатов. Вся эта победа происходит за счет сохранения еще одной копии вашей колонки.

1

Другие решения

Перейдите на MySQL или Postgres. SQLite имеет свои пределы.

0

По вопросам рекламы [email protected]