SierraSoftworks/Iridium

Automatic index creation not working

Manusan42 opened this issue · 3 comments

Hi there,
I have a problem with index generation, but first my specs:
OS: Win10 64bit
node: v8.0.0
mongodb: v3.4.4 (64bit)
some of my dependencies which could be of importance:

"typescript": "2.4.0"
"reflect-metadata": "0.1.10",
"inversify": "4.1.1",
"iridium": "7.2.2",

I have a special structure in my code which differs a lot from default recommendation (mainly because I try to use inversify in a proper way), so I hope the following (densed) snippet will be information enough.
I think most of this is not important, but just for giving a context.

The Core is created like that:

import { decorate, inject, injectable, unmanaged } from 'inversify';
import { Core } from 'iridium';

decorate(injectable(), Core);
decorate(unmanaged(), Core, 0);
decorate(unmanaged(), Core, 1);

@injectable()
export class Database extends Core {
  constructor() {
    super({ database: 'test', host: 'localhost', port: 27001 });
  }
}

Here is the model which is used in my test case:

import { Model, Collection, Index, Instance, ObjectID, Property } from 'iridium';
import { inject, injectable } from 'inversify';
import { TypeKeys } from '../types';

interface Unit {
  _id?: string;
  key: string;
  description?: string;
}

@injectable()
@Collection('units')
@Index({ key: 1 }, { unique: true })
export class UnitModel extends Instance<Unit, UnitModel> implements Unit {
  @ObjectID
  _id?: string;

  @Property(String, true)
  key: string;

  @Property(String, false)
  description?: string;
}

interface UnitService extends Model<Unit, UnitModel> { }

decorate(injectable(), Model);
decorate(unmanaged(), Model, 1);

@injectable()
export class UnitServiceImpl extends Model<Unit, UnitModel> implements UnitService {
  constructor(@inject(TypeKeys.Database) db) {
    super(db, UnitModel);
  }
}
...

The UnitService is injected into a Handler-class and is called with an event:

...
@injectable()
export class UnitHandlerImpl implements Types.UnitHandler {
  @inject(TypeKeys.UnitService) private _unitService: Types.UnitService;

  async create(unit: Unit): Promise<Service.Response> {
    const unitInstance: UnitModel = await this._unitService.insert(unit);
    return new Service.SuccessResponse({ payload: <Unit>(unitInstance.toJSON()) });
  }
}

Actual behavior:
All is working fine, except the index for key ist not created. Even more, it does not matter how I try to create indices, I tried multiple keys, unique or not and even mith the alternate syntax (static property) without the @Index decorator: it always generates just the default _id_ index and nothing more. After each try I've dropped the collection.

Expected behavior:
So I'am not even sure if this is the expected behavior, but I would expect, the index is created automtically when the collection is created by calling the insert()-method.

Just an additional question in advance: After the index creation works, is it supposed that the index is updated accordingly to my code changes even if the collection already exists (with or without entries)?

Best regards

Hi @Manusan42

Thanks for the really comprehensive code examples you sent through, certainly helps narrow down potential causes. One thing I did notice is that at no point are you calling Model.ensureIndexes, which is likely why you're not seeing the indexes being created.

Just a bit of background there, Iridium tries to give you a bit of control over exactly when in your process' lifecycle you create indexes (large applications may decide to do this as part of an upgrade tool, smaller ones may decide to ensure that they're present on each application start) - with that in mind, the @Index decorator is just a means of populating the configuration for an eventual Model.ensureIndexes call somewhere in your code.

My recommendation, if you're working on something that doesn't have heavy DB performance constraints and/or are not changing indexes frequently, is to use the Core.onConnected hook and create indexes for your various models there.

Let me know if you've got any other questions or if you are in fact doing so and it is not working correctly.

Regards,
Benjamin

Super! So many thanks to you, thats exactly what I've missed.
I'm pretty sure this is implemented in some test cases, but it's not mentioned in the examples on main page, but it's such an essential thing, thus it should be mentioned there! And I (and I think many others too) am just too lazy to go through the test cases to find my luck ;-)

Thats also one of my few improvement suggestions: The TypeDoc documentation is great but there are so few examples for all these great features.

Best regards and have a nice day!

Thank you both, this helped me resolve my missing index issue. This info should be included in the main documentation.