Вы можете сделать это с помощью $unwind
в массиве updates
, отсортировав результирующие документы с помощью date
, а затем $group
объединив их на _id
, используя отсортированный порядок.
db.servers.aggregate(
{$unwind: '$service.apps.updates'},
{$sort: {'service.apps.updates.date': 1}},
{$group: {_id: '$_id', 'updates': {$push: '$service.apps.updates'}}},
{$project: {'service.apps.updates': '$updates'}})
Можно найти некоторую информацию об этом в ошибке 4365406 и в алгоритме для вычислений serialVersionUID. В основном, при изменении инициализации Вашего static
участник с System.getProperty()
, компилятор представляет новое static
свойство в Вашем классе, ссылающемся System
класс (я предполагаю что System
класс был ранее не имеющим ссылки в Вашем классе), и так как эта собственность, представленная компилятором, не является частной, это принимает участие в serialVersionUID
вычисление.
Мораль: всегда используйте явный serialVersionUID
, Вы сохраните некоторые циклы ЦП и некоторые головные боли :)
Автоматический serialVersionUID вычисляется на основе членов класса. Их можно показать для файла класса с помощью javap инструмента в JDK солнца.
В случае, упомянутом в вопросе, участник, который добавляется/удаляется, является статическим инициализатором. Это появляется как () V в файлах класса. Содержание метода может быть демонтировано с помощью javap-c. Необходимо смочь разобрать System.getProperty ("нечто") вызов и присвоение на MYSTRING. Однако присвоение со строковым литералом (или любое время компиляции, постоянное, как определено Спецификацией языка Java), поддерживается непосредственно файлом класса, таким образом устраняя необходимость статического инициализатора.
Общий падеж для кода, предназначающегося для J2SE 1.4 (использование - источник 1.4 - предназначаются 1.4) или ранее, является статическими полями к старым Экземплярам класса, которые появляются как литералы класса в исходном коде (MyClass.class). Экземпляр класса ищется по требованию с Class.forName и сохраненным в статическом поле. Именно это статическое поле разрушает serialVersionUID. От J2SE 5.0 вариант ldc кода операции оказывает прямую поддержку литералам класса, устраняя необходимость синтетического поля. Снова, все это можно показать с javap-c.
Я обновил вопрос быть более ясным. Я понимаю, почему инициализация с литералом изменяется serialVersionUID
но не, почему динамическая инициализация изменяет его. Если Вы инициализируете с методом, значение, конечно, может всегда отличаться.
Установка serialVersionUID
явно прекрасен в последующей версии класса, только если Вы уверены, что это - безопасное изменение.
Если я считал спецификацию правильно автоматическое serialVersionUID
не должен изменяться, если Вы изменяете значение помех переходного поля. Смотрите на Главу 5.6 Спецификации.
Однако, если Вы думаете об этом немного - Вы запускаете путем сериализации объекта, который имеет static int MYINT = 3
, когда Вы затем десериализуете класс, Вы ожидаете возвращать тот же объект, то есть, с MYINT = 3
. Так, при изменении статической инициализации, Вы ожидали бы serialVersionUID
измениться, потому что Вы не можете вернуть тот же объект снова.
Так или иначе сохраните это во всех своих сериализуемых классах, и можно управлять serialVersionUID
:
private static final long serialVersionUID = 7526472295622776147L;