Uploaded image for project: 'Node.js Driver'
  1. Node.js Driver
  2. NODE-3981

Investigate NODE-3980 - Class based collections

    • Type: Icon: Task Task
    • Resolution: Done
    • Priority: Icon: Unknown Unknown
    • None
    • Affects Version/s: None
    • Component/s: None
    • Labels:
    • Not Needed

      NODE-3980 Description

      How are you using Mongo? What version of the server and driver are you using?

      I'm using MongoDB 4.4.3 and the 4.3.1 version of the Node driver, as well as Typescript 4.5.5. I'm using MongoDB for a large app back end.

      What is the feature/improvement you would like?

      I think it would be neat if the collection constructor accepted classes (as well as Db.collection). The collection's find, findOne, etc. methods could call the class's constructor with the returned doc as the parameter. This would make the returned object a class and you could define instance methods and them call those on the returned documents. Here is how the syntax may look in Typescript:

      /*
       * model.ts
       */
      
      // Type to remove methods from the class for the ctor
      export type Methodless<T> = {
        [P in keyof T as T[P] extends Function ? never : P]: T[P];
      };
      
      export class MyAwesomeModel extends SomeSuperModel {
        _id: ObjectId;
        prop1?: number;
        prop2?: string;
        
        constructor({ _id, prop1, prop2, ...props}: Methodless<MyAwesomeClass>) {
          super(props);
          this._id = _id;
          this.prop1 = prop1;
          this.prop2 = prop2;
        }
      
        superCoolFunction() {
          console.log(this.prop1);
        }
      }
      
      ...
      
      /*
       * logic.ts
       */
      
      import { MyAwesomeModel } from "./model.ts";
      
      ...
      
      const myawesomemodels = db.collection(MyAwesomeModel);
      
      // now theoretically since we created the collection with the class
      // fetched documents will pass the raw object into the constructor and
      // return the constructed class instead
      // we can also use the MyAwesomeModel.name.lower() for
      // the collection name
      
      (await myawesomemodels.findOne({ prop1: 10 })).superCoolFunction()
      // would print "10"

      What use case would this feature/improvement enable?

      It would essentially allow models to have member functions, and would allow a more object oriented approach. Currently to enable this you have to write your own custom wrapper, call the constructor every time you fetch a document yourself, (error prone) or use static methods, none of which are convenient.

            Assignee:
            Unassigned Unassigned
            Reporter:
            dbeng-pm-bot PM Bot
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: