Here is an approach that combines the normal mongeez changesets with supplementary ones, written in java and works well.
From mongo 3 onwards, map reduce does not work from javascript migration files, so the java approach may be useful in a wider range of migration scenarios.
public class DatabaseMaintenance {
private List<SupplementaryChangeSet> supplementaryChangeSets;
@Autowired
public DatabaseMaintenance(SupplementaryChangeSets supplementaryChangeSets) {
this.supplementaryChangeSets = supplementaryChangeSets.get();
}
public void perform(DB db) {
runMongeezChangesets(db);
runSupplementaryChangesets(db);
}
// Run conventional js or xml migration scripts
private void runMongeezChangesets(DB db) {
Mongeez mongeez = new Mongeez();
mongeez.setMongo(db.getMongo());
mongeez.setDbName(db.getName());
mongeez.setFile(new ClassPathResource("db-maintenance/mongeez.xml"));
mongeez.process();
}
// Run additional changesets that do not fit into js or xml form
private void runSupplementaryChangesets(DB db) {
MongeezDao dao = new MongeezDao(db.getMongo(), db.getName());
for (SupplementaryChangeSet changeSet : supplementaryChangeSets) {
if ( ! dao.wasExecuted(changeSet) && changeSet.perform(db)) {
dao.logChangeSet(changeSet);
}
}
}
}
public abstract class SupplementaryChangeSet extends ChangeSet {
public abstract boolean perform(DB db);
}
public class SupplementaryChangeSets {
@Resource
private ThumbnailGenerationChangeSet thumbnailGenerationChangeSet;
public List<SupplementaryChangeSet> get() {
return asList(thumbnailGenerationChangeSet);
}
}
@Component
public class ThumbnailGenerationChangeSet extends SupplementaryChangeSet {
@Override
public boolean perform(DB db) {
// ... do stuff in java ...
}
}