Как сделать систему поиска по частичному тексту без учета регистра, которая использует Regex с MongoDB и PHP? - PullRequest
0 голосов
/ 04 августа 2020

Я пытаюсь улучшить панель поиска в своем приложении. Если пользователь набирает «Titan» в строке поиска прямо сейчас, приложение будет извлекать mov ie «Titani c» из MongoDB каждый раз, когда я использую следующую функцию регулярного выражения:

require 'dbconnection.php';
if ($_SERVER["REQUEST_METHOD"] == "POST") {
   $input= $_REQUEST['input'];
$query=$collection->find(['movie' => new MongoDB\BSON\Regex($input)]);
}

I также может сделать коллекции нечувствительными к регистру, создав следующий индекс в оболочке Mon go, поэтому, если пользователь вводит «tiTAnI c» в строку поиска, приложение извлекает mov ie «Titani c» из MongoDB:

db.createCollection("c1", { collation: { locale: 'en_US', strength: 2 } } )
db.c1.createIndex( { movie: 1 } )

Однако я не могу сочетать эти две функции одновременно. Указанный выше индекс удалит чувствительность к регистру только тогда, когда я изменю свой запрос на это:

$query=$collection->find( [ 'movie' => $input] );

Если я использую запрос регулярного выражения вверху в тандеме с сопоставленным индексом, он будет игнорировать часть регулярного выражения, поэтому, если Я набираю «Титан», ничего не получается; если я наберу «Titani c», он успешно получит «Titani c» (потому что «Titani c» - это точное слово, хранящееся в моей базе данных).

Есть какие-нибудь советы?

1 Ответ

0 голосов
/ 04 августа 2020

Остерегайтесь: Поиск регулярных выражений в индексированном столбце повлияет на производительность, как указано в $ regex docs :

Запросы с регулярными выражениями без учета регистра обычно не могут эффективно использовать индексы. Реализация $ regex не учитывает параметры сортировки и не может использовать индексы без учета регистра.

Ваша проблема в том, что MongoDB использует префикс (например, /^acme/) в $regex для поиска по индексу.

Для запросов регулярных выражений с учетом регистра, если для поля существует индекс, то MongoDB сопоставляет регулярное выражение со значениями в индексе, что может быть быстрее, чем коллекция сканировать. Дальнейшая оптимизация может произойти, если регулярное выражение является «префиксным выражением», что означает, что все возможные совпадения начинаются с одной и той же строки. Это позволяет MongoDB создавать «диапазон» из этого префикса и сопоставлять только те значения из индекса, которые попадают в этот диапазон.

Поэтому его нужно изменить следующим образом:

$query=$collection->find(['movie' => new MongoDB\BSON\Regex('^'.$input, 'i')]);

Я предлагаю вам разработать свою коллекцию более тщательно.

По теме:

...