Поиск в базе данных MySQL - несериализованные данные

0

Ситуация: У меня есть модель пользователя. атрибут "meta_data" в db представляет поле типа "текст". В модели она сериатизируется пользовательским классом. (serialize :meta_data, CustomJsonSerializer.new)

Это означает, что когда у меня есть экземпляр пользователя, я могу работать с meta_data как с Hash.

User.first.meta_data['username']

Проблема:

Мне нужно написать функцию поиска, которая будет искать пользователей по заданной строке. Я могу сделать это, выполнив поиск по поиску вручную в rails ex. User.where("email LIKE '%#{string}%'")... Но как насчет meta_data? Должен ли я искать в этом поле также выражение LIKE? Если я это сделаю, это уменьшит релевантность найденной записи.

Например:

У меня 2 пользователя. У одного из них есть имя пользователя "patrick", другое - "sergio",

метаданные в db будут выглядеть так:

1) {имя пользователя: patrick}

2) {имя пользователя: sergio}

Я хочу найти sergio, я ввожу строку поиска "ser" =>, но у меня есть 2 результата, а не один. Эта строка meta_data "{uSERname: Patrick}" также имеет "ser", поэтому эта запись не имеет значения.

У вас есть идея, как его решить?

Теги:
deserialization
serialization

1 ответ

0
Лучший ответ

Это действительно проблема с сериализованными данными. Теоретически сериализация может быть алгоритмом, который является очень непостижимым. Он может кодировать Hoffman или другое сжатие и хранить сериализацию в двоичном формате. Вы полагаетесь на предположение, что сериализация использует JSON, и ваша строка будет по-прежнему отображаться как подстрока в сериализации.

Тогда проблема, с которой вы сталкиваетесь, - это еще одна проблема. Другие данные в сериализации могут испортить ваши результаты.

В общем, если вы сериализуете данные, вы делаете выбор, чтобы не быть доступным для поиска.

Таким образом, решение состоит в том, чтобы добавить дополнительное поле, которое вы заполняете таким образом, каким вы управляете. Имейте поле значений и сохраните значение, ограниченное каналом (|), которое вы можете искать. Поэтому, если данные являются {firstname: "Patrick", lastname: "Stern"}, поле meta_values может быть "Patrick | Stern".

Кроме того, не используйте метод where со строкой С# {} расширением входных значений. Это делает его уязвимым для SQL-атак. Вместо этого используйте:

where("meta_values is like :pattern", pattern: "%#{string}%")

Я знаю, что это может выглядеть не совсем по-другому, но ActiveRecord будет проходить санировку таким образом. Если у кого-то есть строка с двоеточием в строке, то ActiveRecord будет избегать полуколонии в условии поиска.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню