Поиск сериализованных данных с использованием активной записи

Я пытаюсь сделать простой запрос сериализованного столбца, как вы это делаете?

serialize :mycode, Array 1.9.3p125 :026 > MyModel.find(104).mycode MyModel Load (0.6ms) SELECT `mymodels`.* FROM `mymodels` WHERE `mymodels`.`id` = 104 LIMIT 1 => [43565, 43402] 1.9.3p125 :027 > MyModel.find_all_by_mycode("[43402]") MyModel Load (0.7ms) SELECT `mymodels`.* FROM `mymodels` WHERE `mymodels`.`mycode` = '[43402]' => [] 1.9.3p125 :028 > MyModel.find_all_by_mycode(43402) MyModel Load (1.2ms) SELECT `mymodels`.* FROM `mymodels` WHERE `mymodels`.`mycode` = 43402 => [] 1.9.3p125 :029 > MyModel.find_all_by_mycode([43565, 43402]) MyModel Load (1.1ms) SELECT `mymodels`.* FROM `mymodels` WHERE `mymodels`.`mycode` IN (43565, 43402) => [] 

В принципе, вы не можете. Недостатком #serialize является то, что вы обходите собственные абстракции своей базы данных. Вы в значительной степени ограничены загрузкой и сохранением данных.

Тем не менее, один очень хороший способ замедлить ваше приложение при обходе может быть:

 MyModel.all.select { |m| m.mycode.include? 43402 } 

Мораль истории: не используйте #serialize для любых данных, которые нужно запросить.

Это всего лишь трюк, чтобы не замедлить ваше приложение. Вы должны использовать .to_yaml .

точный результат:

 MyModel.where("mycode = ?", [43565, 43402].to_yaml) #=> [# 

Протестировано только для MySQL.

Сериализованный массив хранится в базе данных, в частности, например:

 [1, 2, 3, 4] in 1\n 2\n 3\n etc 

следовательно, запрос будет

 MyModel.where("mycode like ?", "% 2\n%") 

введите пробел между % и 2 .

Ответ Нудла прав, но не совсем правильный.

Это действительно зависит от используемого вами адаптера базы данных / ORM: например, PostgreSQL теперь может хранить и искать хеши / json – проверить hstore. Я помню, как читал, что адаптер ActiveRecord для PostgreSQl теперь обрабатывает его правильно. И если вы используете mongoid или что-то в этом роде, тогда вы используете неструктурированные данные (т.е. json) на уровне базы данных везде.

Однако, если вы используете db, который не может обрабатывать hashи, например, комбинацию MySQL / ActiveRecord, то единственная причина, по которой вы будете использовать сериализованное поле, – это somet-данные, которые вы можете создавать / записывать в каком-то фоновом процессе и отображать / выводить по требованию – только два использования, которые я нашел в своем опыте, – это некоторые отчеты (например, поле stat на модели продукта – где мне нужно хранить некоторые средние и медианы для продукта) и пользовательские параметры (например, их предпочтительный цвет шаблона – я действительно не нужно запрашивать об этом) – однако информация о пользователе – например, их подписка для списка рассылки – должна быть доступна для поиска по электронной почте.

PostgreSQL hstore ActiveRecord Пример:

 MyModel.where("mycode @> 'KEY=>\"#{VALUE}\"'") 

Хорошие новости! Если вы используете PostgreSQL с hstore (что очень просто с Rails 4), теперь вы можете полностью искать сериализованные данные. Это удобное руководство, и вот синтаксическая документация от PG.

В моем случае у меня есть словарь, хранящийся как hash в столбце hstore, называемом amenities . Я хочу проверить пару запрашиваемых удобств, которые имеют значение 1 в хеше, я просто делаю

 House.where("amenities @> 'wifi => 1' AND amenities @> 'pool => 1'") 

Ура для улучшений!

Вы можете запросить сериализованный столбец с помощью оператора sql LIKE.

  MyModel.where("mycode LIKE '%?%'", 43402) 

Это быстрее, чем использование include ?, однако вы не можете использовать массив в качестве параметра.

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

Что вы можете сделать, так это создавать таблицы, которые функционируют как индексы для любых данных, которые вы хотите искать.

Создайте модель, содержащую доступные для поиска значения / поля

В вашем примере модели будут выглядеть примерно так:

 class MyModel < ApplicationRecord # id, name, other fields... serialize :mycode, Array end class Item < ApplicationRecord # id, value... belongs_to :my_model end 

Создание таблицы «index» для полей поиска

Когда вы сохраняете MyModel, вы можете сделать что-то вроде этого, чтобы создать индекс:

 Item.where(my_model: self).destroy self.mycode.each do |mycode_item| Item.create(my_model: self, value: mycode_item) end 

Запрос и поиск

Затем, когда вы хотите выполнить запрос и выполнить поиск, выполните следующие действия:

 Item.where(value: [43565, 43402]).all.map(&:my_model) Item.where(value: 43402).all.map(&:my_model) 

Вы можете добавить метод в MyModel, чтобы сделать это проще:

 def find_by_mycode(value_or_values) Item.where(value: value_or_values).all.map(&my_model) end MyModel.find_by_mycode([43565, 43402]) MyModel.find_by_mycode(43402) 

Чтобы ускорить работу, вам нужно создать индекс SQL для этой таблицы.

  • grep файл, но показывать несколько окружающих линий?
  • MySQL - Как сделать заказ? Таблица INNODB
  • Поиск в ArrayList с пользовательскими объектами для определенных строк
  • Сценарий PowerShell для поиска и замены для всех файлов с определенным расширением
  • MySQL find_in_set с несколькими поисковыми строками
  • pandas loc против iloc против ix против vs. iat?
  • Поиск повторяющихся значений в arraylist
  • Как добавить папку в путь поиска сборки во время выполнения в .NET?
  • Как реализовать функцию поиска на веб-сайте?
  • Исключить папки из поиска Eclipse
  • Java - регулярное выражение, содержащее комментарии в коде
  • Давайте будем гением компьютера.