2017-04-11 9 views
1

私は、mongooseクエリとmongodbクエリの間にキャッシングレイヤーを実装するためにES6クラス階層を作成しようとしていました。私はこのPRを見たhttps://github.com/Automattic/mongoose/pull/4668とそれに基づいて、以下のコードを書いた。メソッドは、派生クラスでオーバーライドされているので継承チェーンを持つES6クラスとしてのマングースモデル

'use strict' 

const mongoose = require('mongoose'); 
mongoose.connect("mongodb://host:port/db", {}); 
mongoose.connection.on('error', console.error.bind(console, 'DB connection failed', arguments)); 
mongoose.connection.once('open', console.log.bind(console, 'Connected to DB')); 

class Base extends mongoose.Model { 
    save() { 
     console.log('Base class save()') 
     return super.save(); 
    } 

    findOne(query){ 
     console.log('Base class find...'); 
     return super.findOne(query); 
    } 
} 

class Derived extends Base{ 
    save(){ 
     console.log('Derived class save()'); 
     super.save(); 
    } 

    static getOne(){ 
     console.log('Derived class Get one'); 
     return this.findOne({}); 
    } 
} 

let usersSchema = new mongoose.Schema({ name: String }) 

usersSchema.loadClass(Derived); 

let User = mongoose.model(Derived, usersSchema, 'users'); 

setTimeout(function(){ 
    User.getOne() 
      .then(user => console.log('Found user...', user)); 

    let newUser = new User(); 
    console.log('newUser instance of Derived ? ', (newUser instanceof Derived)); 
    console.log('newUser instance of Base ? ', (newUser instanceof Base)); 
    newUser.name = 'Tony'; 
    newUser.save() 
       .then(result => console.log('Saved', result)); 
}, 2000); 

は、私は順番に基本クラスを呼び出しますし、私は前に/クエリの後に基底クラスに追加ロジックを追加することができます派生クラスでメソッドの呼び出しを期待していました。

以下は、メソッドの呼び出しがDerived/Baseクラスに当たらないことを示しています。

出力

Connected to DB 
Derived class Get one 
newUser instance of Derived ? true 
newUser instance of Base ? true 
Base class save() 
Found user... { _id: 58ec765f9dd99f049c2a833b, name: 'Tony', __v: 0 } 

私はsaveメソッドを呼び出すと、それは派生クラスをヒットしていないと私はクラスを派生中にgetone静的メソッドを呼び出すときに、呼び出しはヒットしません。 findOneメソッドベースクラス。どこが間違っているのか分かりません。誰もこれにいくつかの光を投げることができます。

+0

...ちょっとひどく、文書化、または多分私は右のドキュメントを逃しました!キャッシュの実際の使用も素晴らしいでしょう。新しいデータを保存するときにキャッシュを更新する場合は、キャッシュされたデータを配信するのは、既存のマングースコードに多くのコードを混ぜるのではなく、かなり単純です。 – Gntem

+0

ありがとう@ Mr.Phoenix。 mongooseミドルウェアを使用することを考えた。しかし、私はキャッシュからデータを取得する場合、検索クエリを中止する方法を見つけることができませんでした。 next()を呼び出すのではなく、ミドルウェアからデータを返すことはありますか?私はdoneオプションも見てきましたが、これはセーブフックにのみ適用されると思います。私の理解は正しいのですか? – Tony

+0

あなたはmongooseモデルのfindを呼び出す前にキャッシュをチェックするか、ミドルウェアを使用して、カスタムエラー 'next(err)'を投げてクエリを中止することができます。 – Gntem

答えて

2

私は文字通りこの問題に直面しています。ここで

は、私が働いてしまったコードです:

class User extends mongoose.Model { 
    constructor(user) { 
     super(user); 
     this.settings = new UserSettings({userId: this._id}); 
    } 

    async save(callback) { 
     try { 
      await this.settings.save(); 
      return super.save(callback); 
     } 
     catch (error) { 
      throw error; 
     } 
    } 

    //implement only if you want to use create... 
    static async create(obj, callback) { 
     let user = new User(obj); 
     return user.save(callback); 
    } 
} 

私はあなたがこのようにレースの効果を持つ、asyncキーワードが欠落していると思います。

は私の代わりに(ドキュメント以下)を let prt = new Parent({}).save()を行うので、あなたが親を作成するときに、自動的に(デフォルト値で)サブ文書を作成するには、このコードを作成しました: Parent.find({id: prt.id}).populate('child')

マングースのミドルウェアを使用しない理由は

+0

これを遅らせてください。それの非同期部分を知ることは良いことです。私はasync/awaitキーワードをまだ使用するつもりはない。しかし、実装の観点から見ると、非同期部分以外の上記のアプローチで何か間違っていますか? – Tony

+0

わかりませんが、Derived save()関数でreturn文を追加する必要があります。 – HRK44

関連する問題