Методы для запроса набора объектов в памяти в приложении Java - PullRequest
8 голосов
/ 18 мая 2010

У нас есть система, которая выполняет «грубый поиск», вызывая интерфейс в другой системе, которая возвращает набор объектов Java. Как только мы получили результаты поиска, мне нужно иметь возможность дополнительно фильтровать результирующие объекты Java на основе определенных критериев, описывающих состояние атрибутов (например, из исходных объектов возвращаются все объекты, где xy> z && ab == c).

Критерии, используемые для фильтрации набора объектов каждый раз, частично настраиваются пользователем, под этим я подразумеваю, что пользователи смогут выбирать значения и диапазоны для сопоставления, но атрибуты, из которых они могут выбирать, будут фиксированным набором.

Наборы данных могут содержать <= 10000 объектов для каждого поиска. Поиск будет выполняться вручную базой пользователей приложения, вероятно, не более 2000 раз в день (приблизительно). Вероятно, стоит упомянуть, что все объекты в наборе результатов являются известными классами объектов домена, которые имеют аннотации Hibernate и JPA, описывающие их структуру и отношения. </p>

Возможные решения

С макушки головы я могу придумать 3 способа сделать это:

  1. Для каждого поиска сохраните исходные объекты набора результатов в нашей базе данных, а затем используйте Hibernate, чтобы повторно запросить их, используя более точные критерии.
  2. Используйте базу данных в памяти (например, hsqldb?) Для запроса и уточнения начального набора результатов.
  3. Напишите некоторый пользовательский код, который повторяет исходный набор результатов и извлекает нужные записи.

Вариант 1

Вариант 1, по-видимому, включает в себя множество операций по сети с физической базой данных (Oracle 10g), что может привести к большой сетевой и дисковой активности. Также потребуется, чтобы результаты каждого поиска были изолированы от других наборов результатов, чтобы гарантировать, что различные поиски не мешают друг другу.

Вариант 2

Вариант 2 кажется хорошей идеей в принципе, поскольку он позволил бы мне выполнить более точный запрос в памяти и не требовал бы сохранения данных результата, которые были бы отброшены только после завершения поиска. Суть в том, что это также может быть довольно производительным, но может привести к увеличению объема используемой памяти (это хорошо, поскольку мы можем быть достаточно гибкими в отношении объема памяти, которую получает наша JVM).

Вариант 3

Вариант 3 может быть очень производительным, но я бы хотел этого избежать, поскольку любой код, который мы пишем, потребовал бы такого тщательного тестирования, чтобы время, затрачиваемое на создание чего-то гибкого и достаточно надежного, могло бы быть непомерно высоким.


У меня нет времени на создание прототипа всех 3 идей, поэтому я ищу комментарии, которые могут быть у людей по поводу 3 вариантов выше, плюс любые другие идеи, которые я не рассмотрел, чтобы помочь мне решить, какая идея может быть наиболее подходящей. В настоящее время я склоняюсь к варианту 2 (в базе данных памяти), поэтому хотел бы узнать мнение людей, имеющих опыт запроса POJO в памяти.

Надеюсь, я описал ситуацию достаточно подробно, но не стесняйтесь спрашивать, требуется ли какая-либо дополнительная информация для лучшего понимания сценария.

Приветствия

Edd

Ответы [ 4 ]

1 голос
/ 21 мая 2010

Если ваши выражения не слишком сложны, вы можете использовать язык выражений для оценки строковых запросов к вашим объектам Java (POJO). Я могу порекомендовать MVEL http://mvel.codehaus.org.

Идея состоит в том, что вы помещаете свои объекты в контекст MVEL. Затем вы предоставляете строковый запрос, написанный в соответствии с простыми обозначениями MVEL, и, наконец, вычисляете выражение.

Пример взят с сайта MVEL:

Map vars = new HashMap();
vars.put("x", new Integer(5));
vars.put("y", new Integer(10));

Integer result = (Integer) MVEL.eval("x * y", vars);
assert result.intValue() == 50;  // Mind the JDK 1.4 compatible code :)

Обычно языки выражений поддерживают прохождение вашего графа объектов (коллекций) и доступ к членам в стиле JSP EL (точечная запись).

Кроме того, я могу предложить посмотреть OGNL (Google, я не могу добавить более одной ссылки)

1 голос
/ 19 мая 2010

Опции 1 и 2 вполне совместимы: реализовав один, вы можете заменить его другим с помощью простой перенастройки persistence.xml (учитывая, что база данных в памяти совместима с JPA, например, JavaDB, Derby и т. Д.).

Вариант 3 - повторное внедрение как стороннего программного обеспечения (база данных), так и вашего собственного кода (существующие сущности JPA). Вы также перечислили его преимущества как проблемы. Это явно менее осуществимый вариант в вашем случае. Я не могу придумать что-либо еще для продвижения Варианта 3.

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

0 голосов
/ 19 мая 2010

Вариант 2, кажется, хорош - так как вы можете переключаться между 1 и 2 по мере необходимости. 3 ограничен с точки зрения будущей проблемы определения размера данных. Запросы к объектам подразумевают большую зависимость от структуры кода для хранения и запросов.

Вероятно, было бы неплохо включить некоторый механизм кэширования (ehcache / memcache) наряду с использованием варианта 2, а затем профилировать для проверки разницы в производительности.

0 голосов
/ 18 мая 2010

Насколько сложны критерии очистки? Если большинство из них достаточно просты, я хотел бы начать с варианта (3), но убедитесь, что он инкапсулирован в подходящий интерфейс, так что если вы столкнетесь с чем-то слишком сложным или неэффективным для самостоятельного кодирования, вы может переключиться на БД в памяти в этот момент (либо оптом для всех запросов, либо только для сложных, если есть дополнительные затраты при настройке временных таблиц).

...