【问题标题】:Document Polymorphism in a MongoDb collection using Node.js / MongooseJs -使用 Node.js / MongooseJs 在 MongoDb 集合中记录多态性 -
【发布时间】:2012-10-17 10:55:27
【问题描述】:

我需要维护 [User] 文档的“用户”集合,以便为我的网站实施身份验证机制。

[用户] ~ {color: string, username:string, password-hash:string, password-salt: string}

此外,每个 [User] 可以是 3 种颜色之一 - [RedUser][BlueUser][GreenUser ] 并且会根据颜色有不同的模式。所有扩展自 [User] 架构:

[RedUser] ~ Union( [User],  {redfield:string} )
[GreenUser] ~ Union( [User],  {greenfield:boolean} )
[BlueUser] ~ Union( [User],  {bluefield:number} )

例如一个绿色用户 - {color:'green',username:'bob',password-hash:'1313a...',password-salt:'...'}

对于身份验证,我想使用通用 [User] 架构查询“用户”集合,因为我只需要知道密码哈希。

但是,我想要一个函数如下(伪代码):

Authenticate( username, password )
    userDoc <- users.findOne({username:username})
    if badPassword(usersDoc.password-hash,password) throw error
    else
        if userDoc.color=='red'
            return recast(userDoc, RedUser)
        if userDoc.color=='green'
            return recast(userDoc, BlueUser)
        if userDoc.color=='blue'
            return recast(userDoc, GreenUser)

那么,例如,我如何将 [User] 文档向上转换为 [RedUser]

我正在使用 Node.js/MongooseJs/Coffeescript

谢谢!

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    真的很简单,我们只使用来自https://github.com/briankircho/mongoose-schema-extend 的小而有用的mongoose-schema-extend

    ###
        Dependencies.
    ###
    
    mongoose = require('mongoose')
    extend = require('mongoose-schema-extend')
    
    ###
        Main
    ### 
    
    class Demo
        constructor: (dbUrl)->
            @db = mongoose.createConnection( dbUrl )
    
            userSchema = new mongoose.Schema
                username                    : { type: String, default: "" }                 
                password_hash               : { type: String, default: "" }     
                ,
                {collection : 'users',  discriminatorKey : 'color'}
    
            userSchema.methods.verifyPassword = (pass)->
                console.log("is it a good password? " + (this.password_hash==pass))
    
            redSchema = userSchema.extend
                redfield                : { type: String, default: "red" }          
            redSchema.methods.printColor = ->
                console.log("RED!") 
    
            blueSchema = userSchema.extend
                bluefield           : { type: String, default: "blue" }             
            blueSchema.methods.printColor = ->
                console.log("BLUE!")        
    
            greenSchema = userSchema.extend
                greenfield          : { type: String, default: "green" }                
            greenSchema.methods.printColor = ->
                console.log("GREEN!")               
    
            # create the mongoose db models
            @UserModel = @db.model('User', userSchema)
            @RedModel = @db.model('Red', redSchema)
            @BlueModel = @db.model('Blue', blueSchema)      
            @GreenModel = @db.model('Green', greenSchema)
    
        populate: ->
            user1 = new @RedModel({username:'user1',password_hash:'pass1',redfield:'blabla'})
            user1.save()
            user2 = new @GreenModel({username:'user2',password_hash:'pass2',greenfield:'blabla2'})
            user2.save()    
            user3 = new @RedModel({username:'user3',password_hash:'pass3',redfield:'blabla3'})
            user3.save()        
            user4 = new @GreenModel({username:'user4',password_hash:'pass1',greenfield:'dflabla'})
            user4.save()
            user5 = new @BlueModel({username:'user5',password_hash:'pass2',bluefield:'blabla2'})
            user5.save()    
            user6 = new @BlueModel({username:'user6',password_hash:'pass3',bluefield:'blabla3'})
            user6.save()                
    
        auth:(username,callback)->
            @UserModel.findOne({ username: username }, callback)
    
    ###
        Start the demo
    ###
    
    demo = new Demo('mongodb://localhost/testpolymorph')
    demo.populate()
    demo.auth 'user5', (err,userDoc)->  
        userDoc.verifyPassword("pass")
        userDoc.printColor()
    demo.auth 'user3', (err,userDoc)->
        userDoc.verifyPassword("pass3") 
        userDoc.printColor()
    demo.auth 'user4', (err,userDoc)->
        userDoc.verifyPassword("pass3") 
        userDoc.printColor()    
    

    【讨论】:

      猜你喜欢
      • 2020-05-13
      • 1970-01-01
      • 1970-01-01
      • 2015-10-07
      • 1970-01-01
      • 2013-08-20
      • 2020-05-11
      • 2017-04-20
      • 1970-01-01
      相关资源
      最近更新 更多